直接播放H264视频流的方法或工具
欢迎大家转载,为保留作者成果,转载请注明出处,http://blog.csdn.net/netluoriver,有些文件在资源中也可以下载!如果你没有积分,可以联系我!
前几天在查找资料的时候发现一篇文章特别实用,链接如下:
抓取一个包含H.264 Payload RTP包的SIP会话或RTSP会话后,用Wireshark的Play功能只能播放声音,不能播放视频。把payload直接导出成文件后也是不能直接播放的,因为H.264 over RTP封包是符合RFC3984规范的,必须按照该规范把H.264数据取出来后,组成NALU,放到avi/mp4或裸码流文件等容器里后才能播放。
本人写了一个wireshark插件,可以在打开包含H.264码流的抓包后,选菜单“Tools->Export H264 to file [HQX's plugins]”后,把抓包文件里的H.264码流自动导出到抓包文件所在目录(工作目录)里,名为from_<RTP流源 ip>_<RTP流源端口>_to_<RTP流目的ip>_<RTP流目的端口>.264的264裸码流文件 里。(文件格式为每个NALU前加0x00000001分隔符)。
本程序可以识别RFC3984里提到的三种H.264 over RTP封装,分别是Single NALU(一个RTP含一个NALU)、STAP-A(一个RTP包含多个NALU)、FU-A(一个NALU分布到多个RTP包)三种封装格式,且会自 动把SPS和PPS放到裸码流文件头部。
Lua脚本如下:
-- Dump RTP h.264 payload to raw h.264 file (*.264)-- According to RFC3984 to dissector H264 payload of RTP to NALU, and write it-- to from<sourceIp_sourcePort>to<dstIp_dstPort>.264 file. By now, we support single NALU,-- STAP-A and FU-A format RTP payload for H.264.-- You can access this feature by menu "Tools->Export H264 to file [HQX's plugins]"-- Author: Huang Qiangxiong (qiangxiong.huang@gmail.com)-- change log:-- 2012-03-13-- Just can play------------------------------------------------------------------------------------------------do-- for geting h264 data (the field's value is type of ByteArray)local f_h264 = Field.new("h264") -- menu action. When you click "Tools->Export H264 to file [HQX's plugins]" will run this functionlocal function export_h264_to_file()-- window for showing informationlocal tw = TextWindow.new("Export H264 to File Info Win")local pgtw = ProgDlg.new("Export H264 to File Process", "Dumping H264 data to file...")-- add message to information windowfunction twappend(str)tw:append(str)tw:append("\n")end-- running first time for counting and finding sps+pps, second time for real savinglocal first_run = true -- variable for storing rtp stream and dumping parameterslocal stream_infos = {}-- trigered by all h264 packatslocal my_h264_tap = Listener.new(tap, "h264")-- get rtp stream info by src and dst addressfunction get_stream_info(pinfo)local key = "from_" .. tostring(pinfo.src) .. "_" .. tostring(pinfo.src_port) .. "to" .. tostring(pinfo.dst) .. "_" .. tostring(pinfo.dst_port)local stream_info = stream_infos[key]if not stream_info then -- if not exists, create onestream_info = { }stream_info.filename = key.. ".264"stream_info.file = io.open(stream_info.filename, "wb")stream_info.counter = 0 -- counting h264 total NALUsstream_info.counter2 = 0 -- for second time runningstream_infos[key] = stream_infotwappend("Ready to export H.264 data (RTP from " .. tostring(pinfo.src) .. ":" .. tostring(pinfo.src_port) .. " to " .. tostring(pinfo.dst) .. ":" .. tostring(pinfo.dst_port) .. " to file:\n [" .. stream_info.filename .. "] ...\n")endreturn stream_infoend-- write a NALU or part of NALU to file.function write_to_file(stream_info, str_bytes, begin_with_nalu_hdr)if first_run thenstream_info.counter = stream_info.counter + 1if begin_with_nalu_hdr then-- save SPS or PPSlocal nalu_type = bit.band(str_bytes:byte(0,1), 0x1F)if not stream_info.sps and nalu_type == 7 thenstream_info.sps = str_byteselseif not stream_info.pps and nalu_type == 8 thenstream_info.pps = str_bytesendendelse -- second time runningif stream_info.counter2 == 0 then-- write SPS and PPS to file header firstif stream_info.sps thenstream_info.file:write("\00\00\00\01")stream_info.file:write(stream_info.sps)elsetwappend("Not found SPS for [" .. stream_info.filename .. "], it might not be played!\n")endif stream_info.pps thenstream_info.file:write("\00\00\00\01")stream_info.file:write(stream_info.pps)elsetwappend("Not found PPS for [" .. stream_info.filename .. "], it might not be played!\n")endendif begin_with_nalu_hdr then-- *.264 raw file format seams that every nalu start with 0x00000001stream_info.file:write("\00\00\00\01")endstream_info.file:write(str_bytes)stream_info.counter2 = stream_info.counter2 + 1if stream_info.counter2 == stream_info.counter thenstream_info.file:flush()twappend("File [" .. stream_info.filename .. "] generated OK!\n")end-- update progress window's progress barif stream_info.counter > 0 then pgtw:update(stream_info.counter2 / stream_info.counter) endendend-- read RFC3984 about single nalu/stap-a/fu-a H264 payload format of rtp-- single NALU: one rtp payload contains only NALUfunction process_single_nalu(stream_info, h264)write_to_file(stream_info, h264:tvb()():string(), true)end-- STAP-A: one rtp payload contains more than one NALUsfunction process_stap_a(stream_info, h264)local h264tvb = h264:tvb()local ffset = 1repeatlocal size = h264tvb(offset,2):uint()write_to_file(stream_info, h264tvb(offset+2, size):string(), true)ffset = offset + 2 + sizeuntil offset >= h264tvb:len()end-- FU-A: one rtp payload contains only one part of a NALU (might be begin, middle and end part of a NALU)function process_fu_a(stream_info, h264)local h264tvb = h264:tvb()local fu_idr = h264:get_index(0)local fu_hdr = h264:get_index(1)if bit.band(fu_hdr, 0x80) ~= 0 then-- start bit is set then save nalu header and bodylocal nalu_hdr = bit.bor(bit.band(fu_idr, 0xE0), bit.band(fu_hdr, 0x1F))write_to_file(stream_info, string.char(nalu_hdr), true)else-- start bit not set, just write part of nalu bodyendwrite_to_file(stream_info, h264tvb(2):string(), false)end-- call this function if a packet contains h264 payloadfunction my_h264_tap.packet(pinfo,tvb)local h264s = { f_h264() } -- using table because one packet may contains more than one RTPfor i,h264_f in ipairs(h264s) doif h264_f.len < 2 thenreturnendlocal h264 = h264_f.value -- is ByteArraylocal hdr_type = bit.band(h264:get_index(0), 0x1F)local stream_info = get_stream_info(pinfo)if hdr_type > 0 and hdr_type < 24 then-- Single NALUprocess_single_nalu(stream_info, h264)elseif hdr_type == 24 then-- STAP-A Single-time aggregationprocess_stap_a(stream_info, h264)elseif hdr_type == 28 then-- FU-Aprocess_fu_a(stream_info, h264)elsetwappend("Error: unknown type=" .. hdr_type .. " ; we only know 1-23(Single NALU),24(STAP-A),28(FU-A)!")endendend-- close all open filesfunction close_all_files()if stream_infos thenfor id,stream in pairs(stream_infos) doif stream and stream.file thenstream.file:close()stream.file = nilendendendendfunction my_h264_tap.reset()-- do nothing nowendfunction remove()close_all_files()my_h264_tap:remove()endtw:set_atclose(remove)-- first time it runs for counting h.264 packets and finding SPS and PPSretap_packets()first_run = false-- second time it runs for saving h264 data to target file.retap_packets()-- close progress windowpgtw:close()end-- Find this feature in menu "Tools->"Export H264 to file [HQX's plugins]""register_menu("Export H264 to file [HQX's plugins]", export_h264_to_file, MENU_TOOLS_UNSORTED)end
把代码保存成h264_export.lua文件,放到wireshark安装目录下,然后修改wireshark安装目录下的init.lua文件:
(1)若有disable_lua = true这样的行,则注释掉;
(2)在文件末加入dofile("h264_export.lua")
重新打开wirekshark就能使用该功能了。(低版本的wireshark可能不支持此功能,升级到最新版本即可)
生成的文件在桌面。
另外,264裸码流文件一般播放器不一定能播放,推荐使用ffmpeg的ffplay播放,或用ffmpeg转成通用文件格式播放。
我用的是Elecard_StreamEye测试的,生成的包正常播放。
直接播放H264视频流的方法或工具相关推荐
- unity3d 使用UMP 插件在安卓上 播放H264视频流 不显示问题
此问题是 由于unity3D在安卓上 使用UMP 插件 播放 H264视频流,需要 添加vlc组件:需要在电脑上安装 VLC:然后 在unity3D 上使用, 每次打包时 需要在unity设置界 ...
- html调用rpst 源码_在web页面中播放rtsp直播数据流方法
WEB播放RTSP直播数据流方法 附录一些RTSP测试地址: 1.rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov 一段动画片 2.rtsp: ...
- java rtmp m3u8_RTMP、HLS(M3U8)协议直播视频流网页播放云播放的实现方法
云播放 RTMP.HLS(M3U8)协议 直播视频流网页播放云播放的实现方法,有什么重要意义呢?首先在服务器实现,是云播放,网页播放就是可以产生一个链接,可以放在网站里添加一个链接,也可以发送给好友, ...
- html5播放rtsp h264视频流
最近在研究html5实时播放rtsp流的问题,目前来说h5原生不支持这种格式,网上查了很多教程,大概有以下几种思路. rtsp转rtmp rtmp需要falsh的支持,但是在chrome已经默认禁用. ...
- Qt+FFmpeg播放RTSP H264视频流(1)- 在Qt项目加入FFmpeg库
Qt FFmpeg播放RTSP H264视频流(1) QtCreator引入FFmpeg库 下载FFmpeg库 添加FFmpeg库到Qt项目 测试FFmpeg库是否能正常使用 QtCreator引入F ...
- flash media server播放实时视频流
标签: 图2.连接到电脑的所有摄像头 注意:你可以使用多种摄像头甚至是数字视频录像机来捕获视频.正如FME支持文档中所阐述的那样:Flash Media Live Encoder被用来和微软遭人抱怨的 ...
- 用VC++制作播放AVI视频流的动画按钮
Visual C++ 开发环境为控件提供的自绘制功能使程序员能够充分发挥自己的创造性来设计比较漂亮的程序界面.所谓AVI按钮是指每当鼠标从按钮上经过时就播放一段按钮提示的AVI,在许多的游戏程序以及三 ...
- web无插件解码播放H264/H265(js解码HTML5播放)
项目意义: 长久以来,安防领域的网络摄像机(IPC)的WEB视频直播都依赖于浏览器插件,IE浏览器使用ActiveX插件,Chrome和Firefox浏览器使用NPAPI插件. 之所以开发浏览器插件来 ...
- 轻松实现在web页面中直接播放rtsp视频流
轻松实现在web页面中直接播放rtsp视频流 写在前面 实现 介绍 如何使用 准备ffmpeg 运行rtsp2web 参数说明(在 `new RTSP2web` 时,可配置的参数如下): 前端代码 参 ...
- PHP如何调取vlc播放rtsp,H5+VLC播放RTSP视频流
最新项目涉及到摄像头,这篇文章记录一下在VUE中播放RTSP视频流. 这篇文章主要介绍使用VLC插件播放RTSP视频流,目前支持的浏览器有 360浏览器.2345浏览器,可用于一些对播放器要求不高的项 ...
最新文章
- 【CyberSecurityLearning 附】python3-requests模块
- [IOS]clang diagnostic、Wprotocol ..
- Scala教程之:面向对象的scala
- Linux下locale: Cannot set LC_CTYPE to default locale: No such file or directory警告
- python爬虫:读取PDF
- dev Gridcontrol控件属性部分
- was修改堆内存_WAS问题解决思路
- 11月3日 迅雷白金会员vip账号分享 91freevip 23:00更新
- 获取应用名字、版本号
- PCB分析神器,一键找出Bug
- 如何通俗易懂的解释什么是云服务器?
- 关于杂质过滤的一点研究
- esxi服务器下虚拟机Ubuntu系统搭建PPPoE拨号服务
- 修改本机的 Host 文件
- [经验分享] 覃超直播课学习笔记
- 知识图谱嵌入经典方法(Trans系列、KG2E)
- PGPool-II master/slave mode using caveat
- 【重磅】全球AI芯片排行榜发布 解读入围的七家中国公司
- 企立方电商:拼多多下载安全吗
- JavaSE学习小结二