目前对视频的编码,转码,支持最好的就是 ffmpeg 。由于视频的封装,编码,都是重 cpu 操做,并且目前 python,golang 并无能替代ffmpeg 的库,因此,若是这里不处理图片,使用 python 作 agent 开发效率仍是很高的。目前的作法就是使用 subprocess 调用 ffmpeg ,主要作的是实时解析标准输出,反馈任务的进度。python
该文章后续仍在不断的更新修改中, 请移步到原文地址http://dmwan.ccgit
下面是本身的封装:github
def test_ffmpeg(input_file, output_file, param_list=[]): cmd_list = ["ffmpeg", "-i", input_file] + param_list + [output_file] print "cmd list ", cmd_list p = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=False) fl = fcntl.fcntl(p.stdout.fileno(), fcntl.F_GETFL) fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK) last_out = "" all_time = "" while True: if p.poll() is not None: if p.returncode: data = { "code": 200, "msg": { "error": last_out } } break try: time.sleep(30) out = os.read(p.stderr.fileno(), 1024) if out: last_out = out dura_time = re.findall("Duration:\s\d\d:\d\d:\d\d\.\d\d", out) if dura_time: all_time = dura_time current_time = re.findall("time=\d\d:\d\d:\d\d\.\d\d", out) if len(current_time): data = { "code": 100, "msg": { "all_time": all_time, "current_time": current_time[-1] } } except Exception, e: continue
比较核心的就是实用fcntl, 将管道读取设置成非阻塞,而后有个坑,就是 ffmpeg 的 全部输出都是标准都输出在标准错误输出上。golang
另外,这里使用的是忙轮训的方式去获取标准错误输出。其实,还能够使用 select 去监听 fd,这样会比较省资源。shell
一个subprocess 的标准输出的循环解析封装参考:编码