1. 程式人生 > >(詳細格式)RTMP中FLV流到標準h264、aac的轉換

(詳細格式)RTMP中FLV流到標準h264、aac的轉換

這段時間,工作上的需要,在RTMP上做了flv流到標準h264、AAC的轉換,伺服器是開源專案CRTMPSERVER,客戶端flex編寫,視訊編碼h264,音訊編碼AAC,現將一些協議相關的東西記錄如下。

一、分析FLV資料

我們先拿一個flv檔案來簡單分析一下flv資料的格式

flv標準文件下載地址http://www.cnblogs.com/chef/archive/2012/07/18/2597003.html

flv檔案分析器flvprase下載地址http://www.cnblogs.com/chef/archive/2012/07/18/2596930.html

本文重點不在於此,這塊就跳過了。相信大家對照flv標準文件都能看懂flv資料格式,而且我也強烈建議想學習這塊知識的朋友先把這步的工作完成。

二、分析RTMP上行的h264視訊流

在server上將上行視訊存成二進位制檔案(注意,一定要用二進位制形式儲存資料)如下圖(圖片所顯示的二進位制資料每行有16列資料,即從0至f,如顯示不完全,請單獨開啟圖片檢視)

我使用的工具是notepad++(並安裝二進位制檢視外掛)

如果你有做第一步的工作,不難看出rtmp中flv視訊流就是一個接著一個的Video tag——即FLV tag中去除頭資訊, 只保留video tag內容。

我們對照flv標準文件來逐個分析

17:1-keyframe 7-avc

00:AVC sequence header -- AVC packet type

00 00 00:composition time,AVC時,全0,無意義

因為AVC packet type=AVC sequence header,接下來就是AVCDecoderConfigurationRecord的內容

configurationVersion = 01

AVCProfileIndication = 42

profile_compatibility = 00

AVCLevelIndication = 1f

lengthSizeMinusOne = ff -- FLV中NALU包長資料所使用的位元組數,(lengthSizeMinusOne & 3)+1,實際測試時發現總為ff,計算結果為4,下文還會提到這個資料

numOfSequenceParameterSets = E1 -- SPS 的個數,numOfSequenceParameterSets & 0x1F,實際測試時發現總為E1,計算結果為1

sequenceParameterSetLength = 00 31 -- SPS 的長度,2個位元組,計算結果49

sequenceParameterSetNALUnits = 67 42 80 1f 96 54 05 01 ed 80 a8 40 00 00 03 00 40 00 00 07 b8 00 00 20 00 00 03 01 00 01 fc 63 8c 00 00 10 00                     00 03 00 80 00 fe 31 c3 b4 24 4d 40 -- SPS,為剛才計算的49個位元組, SPS中包含了視訊長、寬的資訊

numOfPictureParameterSets = 01 -- PPS 的個數,實際測試時發現總為E1,計算結果為1

pictureParameterSetLength = 00 04 -- PPS 的長度

pictureParameterSetNALUnits = 68 ce 35 20 -- PPS

接下來又是新的一包videotag資料了

17:1-keyframe 7-avc

01:AVC NALU

00 00 00:composition time,AVC時,全0,無意義

因為AVCPacket type = AVC NALU,接下來就是一個或多個NALU

每個NALU包前面都有(lengthSizeMinusOne & 3)+1個位元組的NAL包長度描述(前文提到的,還記得嗎),前面計算結果為4個位元組

00 00 00 02 :2 -- NALU length

09 10:NAL包

這裡插入一點NALU的小知識,每個NALU第一個位元組的前5位標明的是該NAL包的型別,即NAL nal_unit_type

複製程式碼
#define NALU_TYPE_SLICE 1
#define NALU_TYPE_DPA 2
#define NALU_TYPE_DPB 3
#define NALU_TYPE_DPC 4
#define NALU_TYPE_IDR 5
#define NALU_TYPE_SEI 6
#define NALU_TYPE_SPS 7
#define NALU_TYPE_PPS 8
#define NALU_TYPE_AUD 9  //訪問分隔符
#define NALU_TYPE_EOSEQ 10
#define NALU_TYPE_EOSTREAM 11
#define NALU_TYPE_FILL 12
複製程式碼

09&0x1f=9,訪問單元分隔符

前面我們解析的sps頭位元組為67,67&0x1f = 7,pps頭位元組為68,68&0x1f=8,正好能對應上。

00 00 00 29:說明接下來的NAL包長度為41

06 00 11 80 00 af c8 00 00 03 00 00 03 00 00 af c8 00 00 03 00 00 40 01 0c 00 00 03 00 00 03 00 90 80 08 00 00 03 00 08 80:06&0x1f=6 -- SEI

00 00 3c d0:接下來的NAL包長度

65 88 80……:65&0x1f=5 -- I幀資料

這包video tag分析到此結束了,下面會緊接著來一些該I幀對應的P幀資料, 見下圖

看00003d80那行,前面的內容一直到53 4f 7f都是上一個video tag的內容,即前面說的65 88 80那個I幀的資料拉,27開始是新的一個video tag

27:2-inter frame即P幀,7-codecid=AVC

01:AVCPacket type = AVC NALU

00 00 00:composition time,AVC時,全0,無意義

00 00 00 02 09 30:跟上面分析的一樣拉,2個位元組的nal包,訪問單元分隔符

00 00 00 11:17位元組的NAL包

06 01 0c 00 00 80 00 00 90 80 18 00 00 03 00 08 80:06&0x1f=6-SEI

00 00 46 85: NAL包資料長度

41 9a 02……: 41&0x1f=1,P幀資料

三、轉換

大致總結下flv h264流,按順序依次是

1、一個video tag,包含的資訊:SPS,PPS,訪問單元分隔符,SEI,I幀包

2、一個或多個video tag,包含的資訊:訪問單元分隔符,SEI,P幀包可為多個

迴圈1、2

這裡需要說明下,做轉換這一步時,我們只需要從videotag中獲取到所有的、一個一個的NAL包就可以了,至於它是I幀、P幀及其他型別,實際上我們並不需要關心,這裡只是為了更好的分析資料。

h264的NALU和NALU之間是由00 00 01(也可以是00 00 00 01)分隔開的,我們組成h264之後的格式為

1、00 00 00 01 SPS 00 00 00 01 PPS 00 00 00 01 訪問單元分隔符 00 00 00 01 SEI 00 00 00 01 I幀 00 00 00 01 P幀 00 00 00 01 P幀……(P幀數量不定)

迴圈1

其中的訪問單元分隔符和SEI不是必須的,將h264以二進位制的形式寫入檔案,使用Elecard StreamEye就可以播放了,下載地址

http://www.cnblogs.com/chef/archive/2012/07/18/2597008.html

後記:本人接觸音視訊行業不久,故文中內容不一定完全正確,如果你發現問題,請一定指出謝謝。另文中有極少部分內容有參考網路上一些資料,但實找不出資料原始出處,索性不寫引自何處。

相關推薦

(詳細格式)RTMPFLV標準h264aac轉換

這段時間,工作上的需要,在RTMP上做了flv流到標準h264、AAC的轉換,伺服器是開源專案CRTMPSERVER,客戶端flex編寫,視訊編碼h264,音訊編碼AAC,現將一些協議相關的東西記錄如下。 一、分析FLV資料 我們先拿一個flv檔案來簡單分析一下flv資料的格式 flv標準文件下載地址ht

RTMPFLV標準h264aac轉換

    這段時間,工作上的需要,在RTMP上做了flv流到標準h264、AAC的轉換,伺服器是開源專案CRTMPSERVER,客戶端flex編寫,視訊編碼h264,音訊編碼AAC,現將一些協議相關的東西記錄如下。 一、分析FLV資料     我們先拿一個flv檔案來簡單分析一下flv資料的格式

SRS rtmp http-flv低延時設定測試

配置參考 https://github.com/simple-rtmp-server/srs/wiki/v2_CN_LowLatency 延遲影響因素 編碼器:不同的編碼器(免費或開源的),延遲也是不同的。 流媒體伺服器:SRS2 流協議:比如:rtmp是實時性比較高的,http_flv也是實時性比較高的

ffmpeg複用h264aac為ts

MuxerAndroid.c #include <jni.h> #include <string.h> #include <stdio.h> #include <android/log.h> #include <lib

js對flv提取h264aac音視訊流

# FLV提取裡面的h264視訊流 ### FLV和MP4支援的編碼 ![](//blog.suyuanli.ink/1607829706000-033.png) ### 流媒體和媒體檔案的區別 流媒體是指將一連串的多媒體資料壓縮後,經過網際網路分段傳送資料,在網際網路上即時傳輸影音以供觀賞的一種技術與過

Java的基本資料型別型別轉換規則(自動強制)原反補碼使用者自定義識別符號

基本資料型別 資料型別指明瞭變數和表示式的狀態和行為。 基本資料型別 關鍵字 記憶體中佔用位元組數 取值範圍 布林型 boolean 1位元組(8bit)

Android FFMpeg(三)——使用FFMpeg解碼h264aac

前面部落格記錄了FFMpeg的編譯,編譯後我們可以拿到FFMpeg的動態庫和靜態庫,拿到這些庫檔案後,通常我們需要做個簡單的封裝才能在Android上層愉快的使用。本篇部落格的是從拿到FFMpeg靜態庫到使用FFMpeg解碼視訊的過程,記錄儘可能的詳盡,可能會讓

基於iOS的網路音視訊實時傳輸系統(三)- VideoToolbox編碼音視訊資料為H264AAC

server端 -- 編碼音視訊資料為H264、AAC 這部分花了好多時間,本身就不具備這方面的相關知識,查閱了不少資料,不過關於VideoToolbox和AudioToolbox方面的編碼資料寥寥無幾,雖然網上搜索結果看似特別多,其實一看 內容也大同小異,建議還是看看官方

從wireshark抓包分析rtmp協議,並提取出H264視頻

tmp mage idt 進制 tro shark src 技術 wid 利用wireshark抓取rtmp流數據, 分析到rtmp流後,寫入過濾條件,如 tcp.stream eq 6導出tcp流保存16進制的數據為純文本格式一定要選擇 Hex轉儲,然後點擊 “Sava

在vue接收rtmp視頻並播放,切換視頻源

視頻 end this uid ack vue tex tro ready vue環境 1、包 "video.js": "5.19", "videojs-flash": "2.1.2" 2、html <video id="my-

JAVAIO (讀取鍵盤錄入的詳細講解)

java中鍵盤的錄入 System.out: 對應的是標準輸出裝置,控制檯 初級錄入 程式碼 import java.io.*; public class ReadIn { public static void main(String[] args)thr

(1st week)RTMP的speex音訊與RTP的對接

    之前寫過一篇《RTMP中FLV流到標準h264、acc的轉換》,連結地址 。著重分析了RTMP協議中h264的抽取。     帶音視訊互動的flash專案中,音訊編碼只能選擇speex格式。     這篇文章分為三部分。分別為flex中提供的音訊介面、RTMP中的speex資料、如何轉換為R

Java開發IO的用法詳細解析

練習一:在Java程式設計裡統計一個檔案calcCharNum.txt中字母‘A’和’a’出現的總次數。 package com.test;import java.io.File; import java.io.FileInputStream; import java.io.FileNot

ffmpeg多執行緒本地mp4 rtmph264+aac編碼

程式說明:使用了c++11的std執行緒,鎖,訊號量等東西,替換了pthread多執行緒。主要之前用windows下移植的linux發現多執行緒始終有問題,所以決定用原生的試試。不過現在想來,應該問題還是我佇列的設計問題。主要這裡有個坑,就是c語言for迴圈內部

介面資料格式傳送請求和解析請求

資料流格式傳送請求: HttpClient hc = new HttpClient();             int httpcode = 0;             hc.setConnect

java輸入輸出詳細講解(入門經典),詳細講解JAVA的IO

今天我們開始進入學習 java 中比較讓人頭疼的事, 那就是 I/O 流、多執行緒、網路程式設計。這裡對 I/O 流的一個詳細講解。希望對大家有點用吧。(不看後悔哦) 一、什麼是IO Java中I/O操作主要是指使用Java進行輸入,輸出操作。 Java所有的I/O機制都是基於資料流進行輸入

UML資料圖,用例圖,類圖,物件圖,角色圖,活動圖,序列圖詳細講述

來自 http://my.oschina.net/cmffire/blog/11730?fromerr=KgfrsZGz 作者也是轉載的: 這個文章,是我在急需的情況下在園子裡搜尋到的,原創作者是:DO-websoftware,為了自己看方便,所以複製到我的空間,希望原創者

用nginx搭建http/rtmp/hls協議的MP4/FLV媒體伺服器

前前後後搭建了兩三個星期,終於可以告一段落,nginx實在是有點強大。寫一篇筆記來記錄一下這個過程中的思路和解決方案。 一.搭建nginx平臺: 基本是基於http://blog.csdn.net/xiaoliouc/article/details/8363984 一步步安

rtmp 和 http 協議在播放 flv 媒體的區別

rtmp 是專門為傳輸網路流媒體設計的,需要伺服器(如FMS,awaza等)的支援,對流媒體內容提供比較好的版權保護,另外它本身也需要向adobe支付版權費用。 首先兩者的工作方式不一樣: rtmp 資料需要專門的伺服器接收, 如FMS, awazal等,然後通過本地的

rtmp流轉Hlsflv轉mpegts

rtmp協議是adobe出的一種流媒體格式協議。是目前較為流行的協議的一種。HLS協議是蘋果推出的一種流媒體協議,由於IOS系統不支援RTMP協議,如實現RTMP協議的流媒體需要自己實現RTMP的客戶端,這使得移動手機端使用RTMP的流媒體增加了一些開發成本。HLS協議的詳情