FROM:http://blog.csdn.net/rcfalcon/article/details/6863119

FFMPEG命令行工具目前无法针对视频实时流进行转码,而我们可以用它的新版本提供的支持TCP SERVER的特性来实现这一功能。实现边录边用FFMPEG提供的命令行工具进行转码。(实践证明,FFMPEG 的SDK针对实时流开发比较繁琐,命令行工具相对来说稳定)

我们将实时流录制成正在增长的文件,这样问题就变成了FFMPEG如何针对正在增长的视频文件转码。(首先我们保证视频格式是可以支持正在增长文件解码,这不在本文的讨论范畴)

而我们如果直接使用它对正在增长的文件转码,我们会发现FFMPEG转码到文件末尾(转码速度比录制速度快)就会退出。我们要做的就是在FFMPEG转码到末尾时如何将其挂起。若直接修改FFMPEG的源代码则比较繁琐,我们搭建一个TCP的FILE SERVER,来控制给FFMPEG发送数据的速度,而FFMPEG使用TCP的方式来获取视频流,即可实现这个功能。

以下是代码,我们用python来实现:

FFMPEG version:N-32611-gd55b06b

[python] view plaincopy
  1. #encoding=utf8
  2. '''''
  3. Created on 2011-9-25
  4. @author: chenggong
  5. ffmpeg扩展工具
  6. '''
  7. import SocketServer
  8. import os
  9. import threading
  10. import time
  11. BIN_DIR = "bin\\"
  12. BLOCK_SIZE = 188*1024
  13. FRONTOFFSET = 1024 * 1024 * 1
  14. gparam={'output':'','source':'','port':9333,
  15. 'start':0,'length':0,'ffmpeg_argvs':'',
  16. 'ffmpegsema':None,'tcpserversema':None}
  17. class MyFfmpegThread(threading.Thread):
  18. def run(self):
  19. if os.path.exists(gparam['output']):
  20. os.remove(gparam['output'])
  21. argvs = gparam['ffmpeg_argvs'].replace("[filelocate]","tcp://127.0.0.1:%d"%gparam['port']) + " " + gparam['output']
  22. cmd = "%s\\avconv %s"%(BIN_DIR,argvs)
  23. os.system(cmd)
  24. gparam['ffmpegsema'].release()
  25. class MyTcpServerThread(threading.Thread):
  26. def run(self):
  27. while True:
  28. try:
  29. ADDR = ("127.0.0.1", gparam['port'])
  30. self.tcpServ = SocketServer.ThreadingTCPServer(ADDR, MyRequestHandler)
  31. break
  32. except Exception,e:
  33. print str(e)
  34. print "port:%d 被占用..更换"%gparam['port']
  35. gparam['port']+=1
  36. self.tcpServ.serve_forever()
  37. def close(self):
  38. self.tcpServ.shutdown()
  39. self.tcpServ.server_close()
  40. class MyRequestHandler(SocketServer.BaseRequestHandler):
  41. def handle(self):
  42. print 'connected from:', self.client_address
  43. file = open(gparam['source'],"rb")
  44. startoffset = gparam['start']
  45. if startoffset<0:startoffset=0
  46. print "start offset="+str(startoffset)
  47. file.seek(startoffset)
  48. left = gparam['length']
  49. while(True):
  50. try:
  51. if(left<BLOCK_SIZE and left!=-1):
  52. buffer_size = left
  53. else:
  54. buffer_size = BLOCK_SIZE
  55. data=file.read(buffer_size)
  56. #print "read data,size="+str(len(data))
  57. #if(left!=-1): print "left size=%d"%left
  58. if not data:
  59. print "data empty! read to file_end,wait.."
  60. finish_filename=gparam['source'].replace(os.path.splitext(gparam['source'])[1],".finish")
  61. if(os.path.exists(finish_filename)):
  62. print ".finish file founded"
  63. break
  64. time.sleep(1)
  65. continue
  66. self.request.sendall(data)
  67. if(left!=-1):
  68. left -= buffer_size
  69. if(left<=0):
  70. print "transfer finished"
  71. break
  72. if(len(data)<buffer_size):
  73. finish_filename=gparam['source'].replace(os.path.splitext(gparam['source'])[1],".finish")
  74. if(os.path.exists(finish_filename)):
  75. print ".finish file founded"
  76. break
  77. else:
  78. print "read to file_end,wait.."
  79. time.sleep(1)
  80. except:
  81. print "exception occured,client stopped"
  82. break
  83. print "work finished"
  84. file.close()
  85. gparam['tcpserversema'].release()
  86. def ffmpegex(source,output,start,length,ffmpeg_argvs):
  87. gparam['source']=source
  88. gparam['output']=output
  89. gparam['start']=start
  90. gparam['length']=length
  91. gparam['ffmpeg_argvs']=ffmpeg_argvs
  92. try:
  93. while True:
  94. gparam['ffmpegsema']=threading.Semaphore(0)
  95. gparam['tcpserversema']=threading.Semaphore(0)
  96. tcpServerThread = MyTcpServerThread()
  97. tcpServerThread.start()
  98. MyFfmpegThread().start()
  99. gparam['ffmpegsema'].acquire()
  100. gparam['tcpserversema'].acquire()
  101. tcpServerThread.close()
  102. filesize = os.path.getsize(gparam['output'])
  103. if(filesize<length/10): #生成失败,将start提前,重做任务
  104. if gparam['start']==0: return False
  105. if gparam['start']-FRONTOFFSET>=0:
  106. gparam['start']-=FRONTOFFSET
  107. else:
  108. gparam['start']=0
  109. else:
  110. return True
  111. except:
  112. return False
  113. if __name__ == "__main__":
  114. for i in range(0,100):
  115. import random
  116. start = random.randrange(0,1024*1024*1024)
  117. print ffmpegex('C:\\16942.ts','C:\\test2\\%d-%d.wmv'%(i,start),start,1024*1024*5,\
  118. "-i [filelocate] -acodec wmav2 -vcodec wmv2 -qscale 1 -ab 256k -r 25")

让FFMPEG支持实时流“伴随”转码相关推荐

  1. pyqt5+opencv实现视频播放组件,支持实时流播放

    pyqt5+opencv实现视频播放 详细源码链接为:https://github.com/2500284064/pyqt5-opencv-video 基本原理是通过 VideoCapture 类读取 ...

  2. 视频流异步转码和实时流式转码是什么意思?有什么区别?

    随着互联网带宽的不断提升,视频内容的分发与播放在新闻娱乐.在线教育.社交网络和自媒体场景下越来越普遍,EasyDSS这样的平台作为视频直播点播平台,在越来越多的项目中得到了应用,比如校园课堂.酒店智能 ...

  3. 如何让ffplay或者ffmpeg支持H265编码的rtmp/http-flv 实时直播流

    很多初学者不知道ffplay或者ffmpeg是不支持flv封装的rtmp/http-flv流的,其原因是flv不支持H265编码payload的,因为当时制定flv封装协议的时候,H265还没出来,现 ...

  4. Apache Storm 实时流处理系统通信机制源码分析

    我们今天就来仔细研究一下Apache Storm 2.0.0-SNAPSHOT的通信机制.下面我将从大致思想以及源码分析,然后我们细致分析实时流处理系统中源码通信机制研究. 1. 简介 Worker间 ...

  5. H.264 媒体流 AnnexB 和 AVCC 格式分析 及 FFmpeg 解析mp4的H.264码流方法

    H264码流分两种组织方式,一种是AnnexB格式,一种是AVCC格式. 作者:码农小明 来源:https://blog.csdn.net/shaosunrise/article/details/12 ...

  6. 在已实现spp程序基础上改rtk,附C++源码(事后和实时流)

    原文地址:在已实现spp程序基础上改rtk,附C++源码(事后和实时流) 上面这个链接现在可以下载啦- 换了地址- 因为报告我已经搞丢了 所以只分享我的事后处理以及实时流的计算程序给大家. 事先说明

  7. android flv 编码器,Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载)...

    Android 音视频深入 十七 FFmpeg 获取 RTMP 流保存为 flv (附源码下载) 项目地址 https://github.com/979451341/RtmpSave 这个项目主要代码 ...

  8. 利用ffmpeg录制rtsp流的方法总结(一)

    致敬雷霄骅(已逝):https://blog.csdn.net/leixiaohua1020/article/details/18893769 音频编码 编码技术 算法 编码标准 码率(kbit/s) ...

  9. Nginx-rtmp 直播媒体实时流实现

    0. 前言 这段时间在搭建一个IPCamera项目服务器.视频点对点通话,客户端会查看设备端的音视频实时流.为了省流量,是通过P2P进行穿透.但是由于NAT设备的原因和IPV4的枯竭.有些设备是无法进 ...

最新文章

  1. 型人格 disc测试_3号,成就型人格的专业和职业选择@九型人格测试
  2. Cocos2d-x游戏中默认的AndroidManifest.xml的解析
  3. mysql国际化_Java的Struts框架中的主题模板和国际化设置
  4. drawitem设置指定行的背景颜色_Java 为 Excel 中的行设置交替背景色
  5. RAC集群故障恢复CRS-4047,CRS-4000
  6. 九个数的全排列(避免重复出现)
  7. java修改list中对象的值_Java中List集合的一点总结
  8. SQL高手请进来一下,谢谢
  9. Python面向对象,站在更高的角度来思考
  10. 拆除指令怎么设置_siri叫你起床啦~早安等快捷指令你会用了吗i
  11. Python知识整理_1
  12. IOS 10 微信 ajax readystate=0 status=0 解决方法
  13. 在linux下运行.o文件,Linux环境下在可执行程序中嵌入资源文件
  14. 【史上最全】设计师必备的83个设计资源网站
  15. autocad ios 虚线_autocad 如何画虚线
  16. 富邦速配民营银行管理层动荡浪潮之下,振兴银行再迎新帅
  17. jsp打印去掉页眉页脚
  18. Incorrect string value '\xF0\xA0\x9D\xB9\xE5\x82...' for column 'CONTENT' at row 1
  19. Laya页面嵌套和Scene.destory导致的Bug
  20. shell中的try...catch...

热门文章

  1. java map 迭代遍历_java 遍历Map的四种方式
  2. Shell 数组中 @ 跟 * 的区别
  3. java 建立网站_建立基本的Java Web站点
  4. HTML5表单元素禁用,禁用HTML5表单元素的验证
  5. 深入浅出,Handler机制外科手术式的剖析(ThreadLocal,Looper,MessageQueen,Message)(上)...
  6. Linux多线程总结
  7. 巨人也能身手敏捷?看美国KeyBank的实战经验
  8. 第四节:python if语句用法
  9. puppet自动化运维之exec资源
  10. ssis foreach 使用ADO记录集