add pysox, 2x faster
This commit is contained in:
+4
-7
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: UTF-8 -*-
|
||||
# File: render.py
|
||||
# Date: Thu Dec 25 10:18:20 2014 +0800
|
||||
# Date: Thu Dec 25 22:05:41 2014 +0800
|
||||
# Author: Yuxin Wu <[email protected]>
|
||||
|
||||
import os
|
||||
@@ -20,7 +20,7 @@ except:
|
||||
css_compress = lambda x: x
|
||||
|
||||
from .msg import *
|
||||
from .utils import ensure_unicode, ProgressReporter, pmap
|
||||
from .utils import ensure_unicode, ProgressReporter, pmap, timing
|
||||
from .smiley import SmileyProvider
|
||||
from .msgslice import MessageSlicerByTime, MessageSlicerBySize
|
||||
|
||||
@@ -97,7 +97,6 @@ class HTMLRender(object):
|
||||
return fallback()
|
||||
bigimgpath = self.parser.imginfo.get(msg.msgSvrId)
|
||||
fnames = [k for k in [imgpath, bigimgpath] if k]
|
||||
assert len(fnames) > 0, msg.msg_str()
|
||||
bigimg, smallimg = self.res.get_img(fnames)
|
||||
if not smallimg:
|
||||
logger.warn("No image thumbnail found for {}".format(imgpath))
|
||||
@@ -130,8 +129,6 @@ class HTMLRender(object):
|
||||
|
||||
def _render_partial_msgs(self, msgs):
|
||||
""" return single html"""
|
||||
talker_name = msgs[0].talker
|
||||
avatars = self.get_avatar_pair(talker_name)
|
||||
slicer = MessageSlicerByTime()
|
||||
slices = slicer.slice(msgs)
|
||||
|
||||
@@ -151,12 +148,12 @@ class HTMLRender(object):
|
||||
extra_js=self.js_string,
|
||||
talker=msgs[0].talker_name,
|
||||
messages=u''.join(blocks),
|
||||
avatars=avatars)
|
||||
|
||||
avatars=self.avatars)
|
||||
|
||||
def render_msgs(self, msgs):
|
||||
""" render msgs of one friend, return a list of html"""
|
||||
talker_name = msgs[0].talker
|
||||
self.avatars = self.get_avatar_pair(talker_name)
|
||||
logger.info(u"Rendering {} messages of {}({})".format(
|
||||
len(msgs), self.parser.contacts[talker_name], talker_name))
|
||||
|
||||
|
||||
+16
-11
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: UTF-8 -*-
|
||||
# File: res.py
|
||||
# Date: Thu Dec 25 10:04:29 2014 +0800
|
||||
# Date: Thu Dec 25 23:19:32 2014 +0800
|
||||
# Author: Yuxin Wu <[email protected]>
|
||||
|
||||
import glob
|
||||
@@ -14,9 +14,10 @@ import logging
|
||||
import imghdr
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import eyed3
|
||||
import pysox
|
||||
|
||||
from lib.avatar import AvatarReader
|
||||
from .avatar import AvatarReader
|
||||
from .utils import timing
|
||||
|
||||
LIB_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
INTERNAL_EMOJI_DIR = os.path.join(LIB_PATH, 'static', 'internal_emoji')
|
||||
@@ -53,21 +54,25 @@ class Resource(object):
|
||||
"Error interpreting the protocol, this is a bug!"
|
||||
self.speak_data[key] = full_path
|
||||
|
||||
@timing(total=True)
|
||||
def get_voice_mp3(self, imgpath):
|
||||
""" return base64 string, and voice duration"""
|
||||
amr_fpath = self.speak_data[imgpath]
|
||||
assert amr_fpath.endswith('.amr')
|
||||
mp3_file = os.path.join('/tmp',
|
||||
os.path.basename(amr_fpath)[:-4] + '.mp3')
|
||||
# TODO is there a library to use?
|
||||
ret = os.system('sox {} {}'.format(amr_fpath, mp3_file))
|
||||
if ret != 0:
|
||||
logger.warn("Sox Failed!")
|
||||
return ""
|
||||
mp3_string = open(mp3_file, 'rb').read()
|
||||
duration = eyed3.load(mp3_file).info.time_secs
|
||||
|
||||
infile = pysox.CSoxStream(amr_fpath)
|
||||
outfile = pysox.CSoxStream(mp3_file, 'w', infile.get_signal())
|
||||
chain = pysox.CEffectsChain(infile, outfile)
|
||||
chain.flow_effects()
|
||||
outfile.close()
|
||||
|
||||
signal = infile.get_signal().get_signalinfo()
|
||||
duration = signal['length'] * 1.0 / signal['rate']
|
||||
mp3_string = Resource.get_file_b64(mp3_file)
|
||||
os.unlink(mp3_file)
|
||||
return base64.b64encode(mp3_string), duration
|
||||
return mp3_string, duration
|
||||
|
||||
@staticmethod
|
||||
def get_file_b64(fname):
|
||||
|
||||
+46
-1
@@ -1,11 +1,16 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: UTF-8 -*-
|
||||
# File: utils.py
|
||||
# Date: Thu Dec 25 10:11:21 2014 +0800
|
||||
# Date: Thu Dec 25 16:27:39 2014 +0800
|
||||
# Author: Yuxin Wu <[email protected]>
|
||||
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import time, functools
|
||||
from collections import defaultdict
|
||||
|
||||
def ensure_bin_str(s):
|
||||
if type(s) == str:
|
||||
@@ -111,3 +116,43 @@ def pimap(map_func, iterator, nr_proc=None, nr_precompute=None):
|
||||
def pmap(map_func, iterator, nr_proc=None, nr_precompute=None):
|
||||
'''parallel map'''
|
||||
return list(pimap(map_func, iterator, nr_proc, nr_precompute))
|
||||
|
||||
|
||||
class TotalTimer(object):
|
||||
def __init__(self):
|
||||
self.times = defaultdict(float)
|
||||
|
||||
def add(self, name, t):
|
||||
self.times[name] += t
|
||||
|
||||
def reset(self):
|
||||
self.times = defaultdict(float)
|
||||
|
||||
def __del__(self):
|
||||
for k, v in self.times.iteritems():
|
||||
logger.info("{} took {} seconds in total.".format(k, v))
|
||||
|
||||
_total_timer = TotalTimer()
|
||||
class timing(object):
|
||||
def __init__(self, total=False):
|
||||
self.total = total
|
||||
|
||||
def __call__(self, func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
ret = func(*args, **kwargs)
|
||||
duration = time.time() - start_time
|
||||
|
||||
if hasattr(func, '__name__'):
|
||||
func_name = func.__name__
|
||||
else:
|
||||
func_name = 'function in module {}'.format(func.__module__)
|
||||
if self.total:
|
||||
_total_timer.add(func_name, duration)
|
||||
else:
|
||||
logger.info('Duration for `{}\': {}'.format(
|
||||
func_name, duration))
|
||||
return ret
|
||||
return wrapper
|
||||
|
||||
|
||||
Reference in New Issue
Block a user