从wireshark 抓包中的导出 H.264 变成可用暴风直接播放的H264 裸码流文件
本文转载自:http://blog.csdn.net/cherish_2012/article/details/41014203
在wireshark里面透过 stream analysis,导出来的H264影像没法直接播放,是因为我们需要安装一个插件,Lua脚本如下:
抓取一个包含H.264 Payload RTP包的SIP会话或RTSP会话后,用Wireshark的Play功能只能播放声音,不能播放视频。把RTP payload直接导出成文件后也是不能直接播放的,因为H.264 over RTP封包是符合RFC3984规范的,必须按照该规范把H.264数据取出来后,组成NALU,放到avi/mp4或裸码流文件等容器里后才能播放。
本程序可以识别RFC3984里提到的三种H.264 over RTP封装,分别是Single NALU(一个RTP含一个NALU)、STAP-A(一个RTP包含多个NALU)、FU-A(一个NALU分布到多个RTP包)三种封装格式,且会自动把SPS和PPS放到裸码流文件头部。
-- 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 function
local function export_h264_to_file()
-- window for showing information
local 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 window
function twappend(str)
tw:append(str)
tw:append("\n")
end
-- running first time for counting and finding sps+pps, second time for real saving
local first_run = true
-- variable for storing rtp stream and dumping parameters
local stream_infos = {}
-- trigered by all h264 packats
local my_h264_tap = Listener.new(tap, "h264")
-- get rtp stream info by src and dst address
function 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 one
stream_info = { }
stream_info.filename = key.. ".264"
stream_info.file = io.open(stream_info.filename, "wb")
stream_info.counter = 0 -- counting h264 total NALUs
stream_info.counter2 = 0 -- for second time running
stream_infos[key] = stream_info
twappend("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")
end
return stream_info
end
-- write a NALU or part of NALU to file.
function write_to_file(stream_info, str_bytes, begin_with_nalu_hdr)
if first_run then
stream_info.counter = stream_info.counter + 1
if begin_with_nalu_hdr then
-- save SPS or PPS
local nalu_type = bit.band(str_bytes:byte(0,1), 0x1F)
if not stream_info.sps and nalu_type == 7 then
stream_info.sps = str_bytes
elseif not stream_info.pps and nalu_type == 8 then
stream_info.pps = str_bytes
end
end
else -- second time running
if stream_info.counter2 == 0 then
-- write SPS and PPS to file header first
if stream_info.sps then
stream_info.file:write("\00\00\00\01")
stream_info.file:write(stream_info.sps)
else
twappend("Not found SPS for [" .. stream_info.filename .. "], it might not be played!\n")
end
if stream_info.pps then
stream_info.file:write("\00\00\00\01")
stream_info.file:write(stream_info.pps)
else
twappend("Not found PPS for [" .. stream_info.filename .. "], it might not be played!\n")
end
end
if begin_with_nalu_hdr then
-- *.264 raw file format seams that every nalu start with 0x00000001
stream_info.file:write("\00\00\00\01")
end
stream_info.file:write(str_bytes)
stream_info.counter2 = stream_info.counter2 + 1
if stream_info.counter2 == stream_info.counter then
stream_info.file:flush()
twappend("File [" .. stream_info.filename .. "] generated OK!\n")
end
-- update progress window's progress bar
if stream_info.counter > 0 then pgtw:update(stream_info.counter2 / stream_info.counter) end
end
end
-- read RFC3984 about single nalu/stap-a/fu-a H264 payload format of rtp
-- single NALU: one rtp payload contains only NALU
function 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 NALUs
function process_stap_a(stream_info, h264)
local h264tvb = h264:tvb()
local offset = 1
repeat
local size = h264tvb(offset,2):uint()
write_to_file(stream_info, h264tvb(offset+2, size):string(), true)
offset = offset + 2 + size
until 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 body
local 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 body
end
write_to_file(stream_info, h264tvb(2):string(), false)
end
-- call this function if a packet contains h264 payload
function my_h264_tap.packet(pinfo,tvb)
local h264s = { f_h264() } -- using table because one packet may contains more than one RTP
for i,h264_f in ipairs(h264s) do
if h264_f.len < 2 then
return
end
local h264 = h264_f.value -- is ByteArray
local 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 NALU
process_single_nalu(stream_info, h264)
elseif hdr_type == 24 then
-- STAP-A Single-time aggregation
process_stap_a(stream_info, h264)
elseif hdr_type == 28 then
-- FU-A
process_fu_a(stream_info, h264)
else
twappend("Error: unknown type=" .. hdr_type .. " ; we only know 1-23(Single NALU),24(STAP-A),28(FU-A)!")
end
end
end
-- close all open files
function close_all_files()
if stream_infos then
for id,stream in pairs(stream_infos) do
if stream and stream.file then
stream.file:close()
stream.file = nil
end
end
end
end
function my_h264_tap.reset()
-- do nothing now
end
function remove()
close_all_files()
my_h264_tap:remove()
end
tw:set_atclose(remove)
-- first time it runs for counting h.264 packets and finding SPS and PPS
retap_packets()
first_run = false
-- second time it runs for saving h264 data to target file.
retap_packets()
-- close progress window
pgtw: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")
另外,在过滤栏目输入RTP,可以过滤所有的rtp报文,可以看到type为96.
点击:edit-->preference--》protocol-->H264,填上96,保存即可。
在打开包含H.264码流的抓包后,选菜单“Tools->Export H264 to file [HQX's plugins]”后,把抓包文件里的H.264码流自动导出到抓包文件所在目录(工作目录)里,名为from_<RTP流源ip>_<RTP流源端口>_to_<RTP流目的ip>_<RTP流目的端口>.264的264裸码流文件里。(文件格式为每个NALU前加0x00000001分隔符)。
另外,264裸码流文件一般播放器不一定能播放,推荐使用ffmpeg的ffplay播放,或用ffmpeg转成通用文件格式播放,暴风影音完美支持,只是播放速度快了点
从wireshark 抓包中的导出 H.264 变成可用暴风直接播放的H264 裸码流文件相关推荐
- 将h.264裸码流推送到RTMP服务器
h.264裸码流的格式,参考"H.264-AVC-ISO_IEC_14496-10.pdf, page 211.",这个文档的下载地址:https://github.com/win ...
- Wireshark抓包分析结果中的LG bit和IG bit
Wireshark抓包分析结果中的LG bit和IG bit Wireshark抓包结果中常出现LG bit和IG bit的字段,几乎每个协议包里都能找到,如图下这样: 点击通常会对应6个16进制数( ...
- Wireshark 抓包分析 RTSP/RTP/RTCP 基本工作过程
整体而言,RTSP 通常工作于可靠的传输协议 TCP 之上,就像 HTTP 那样,用于发起/结束流媒体传输,交换流媒体元信息.RTP 通常工作于 UDP 之上,用于传输实际的流媒体数据,其中的载荷格式 ...
- [实战]前端wireshark抓包协议解密
前端wireshark抓包协议解密 废话不多说,先看看结果 该JSON文件是通过解密后的 HTTP 返回response结果再解密打开的新页面 有兴趣的小伙伴了解下之前的文章 Sha384解密[2] ...
- 通过wireshark抓包对nmap一些原理分析
对目标主机的扫描是渗透过程中信息收集阶段的重要组成部分,由于现在大部分的网络都是基于TCP/IP协议栈的,所以根据TCP/IP协议栈的特性进行的扫描往往十分实用,nmap就是众多扫描工具中的佼佼者. ...
- Wireshark抓包原理(ARP劫持、MAC泛洪)及数据流追踪和图像抓取(二)
[网络安全自学篇] 十三.Wireshark抓包原理(ARP劫持.MAC泛洪)及数据流追踪和图像抓取(二) 2019年09月22日 21:55:44 Eastmount 阅读数 3515 文章标签: ...
- Dapp区块链 | wireshark抓包2
这是wireshark抓包的基本用法,使用DApp的IP进行过滤: DApp区块链 | wireshark抓包 今天跟学长交流了一下,发现只使用DApp的IP进行过滤会缺少很多流量包 目录 DApp通 ...
- fiddler 抓包后批量导出_Fiddler抓包13-fiddler 抓包导出 curl 命令行
前言 curl是一个命令行工具 ,一般用于 linux 环境上发 http 请求,方便远程定位接口问题. fiddler 抓包后可以导出 curl 命令行,这样方便不会写 curl 的小伙伴快速的生成 ...
- Wireshark抓包分析基础
Wireshark抓包分析 (仅作为个人笔记,如有雷同,请联系删除..) 下载:https://www.wireshark.org/#download 1.设置时间格式:视图–>时间显示格式 2 ...
- wireshark抓包红色_Wireshark网络抓包(一)——数据包、着色规则和提示
一.数据包详细信息 Packet Details面板内容如下,主要用于分析封包的详细信息. 帧:物理层.链路层 包:网络层 段:传输层.应用层 1)Frame 物理层数据帧概况 2)Ethernet ...
最新文章
- MySQL 性能优化之高阶神技
- pytorch | 深度学习分割网络U-net的pytorch模型实现
- java调用存储过程
- python 结构体数组 定义_一篇文章弄懂Python中所有数组数据类型
- 【Python】Windows下Python3虚拟环境搭建
- 大数据之-Hadoop之HDFS_hadoop集群中的安全模式_原理---大数据之hadoop工作笔记0074
- struts2系列(四):struts2国际化的多种方式
- module.exports与exports,export与export defa
- WPS多版本残留_软件分享猫 wps会员的获取
- CE教程第八步之多级指针
- asp.net970-宠物医院管理系统#毕业设计
- 多电压等级计算机潮流计算,电力系统稳态分析教学心得
- ptt评论量子计算机,PTT网友热议Nuguri替补:打野下路状态都拉跨不换,先换上路??...
- 结构光三维扫描仪(单相机+单投影仪)
- 马云开酒吧了,酒吧叫“平头哥”,真猛~
- unity 制作的app发布到andriod手机
- 玩转Redis-HyperLogLog统计微博日活月活
- 五子棋游戏程序设计制作(C语言)
- 如何为PPT加上页码/总页码
- 摩尔纹的原理与产生条件