从nginx-rtmp中提取一帧h264帧
生活随笔
收集整理的這篇文章主要介紹了
从nginx-rtmp中提取一帧h264帧
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 摘要:一為什么要提取h264幀???因為我們經常需要從事實流中截取一些畫面,用于變動的封面,安全,鑒黃等用處。二從nginx_rtmp中怎么提取一幀h264幀呢???前面我們講過如何提取sps和pps,這里只需要提取一個nalu,如果是I幀就手動把sps和pps添加到幀前面就可以了。三提取實現代碼??可以參照前面sps和pps提取,??從ngx_rtmp_live_av(ngx_rtmp_session
- 一 為什么要提取h264幀??
? ? 因為我們經常需要從事實流中截取一些畫面,用于變動的封面,安全,鑒黃等用處。?
二 從nginx_rtmp中怎么提取一幀h264幀呢??
? ? 前面我們講過如何提取sps和pps,這里只需要提取一個nalu,如果是I幀就手動把sps和pps添加到幀前面就可以了。?
三 提取實現代碼?
? ? 可以參照前面sps和pps提取,?
? ? 從ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,?
? ? ? ? ? ? ? ? ?ngx_chain_t *in)函數入手?
? ? (1)首先我們合并ngx_chain_t *in 數據。?
? ? ngx_str_t tmp_str = {0};?
? ? tmp_str.data = (u_char*)ngx_palloc(s->connection->pool,MAX_TAG_SIZE);?
? ? if(tmp_str.data == NULL)?
{?
return NGX_ERROR;?
}?
ngx_chain_t *tmp_in = NULL;?
int in_len = 0;?
int parse_offset = 0;?
for(tmp_in = in;tmp_in;tmp_in = tmp_in->next)?
{?
memcpy(tmp_str.data + in_len,tmp_in->buf->pos,(int)(tmp_in->buf->last - tmp_in->buf->pos));?
in_len += (int)(tmp_in->buf->last - tmp_in->buf->pos);?
}?
tmp_str.len = in_len;??
? ? ?這里內存申請,統一用nginx自帶的內存池,這樣方便管理,當連接結束的時候,nginx會自動釋放這個內存池。?
? ? ?s->connection->pool。?
? ? ?但是由于我們這個一個tag占用內存太多,因此最好是用一次申請完就釋放掉,或者最好直接保存到會話中,一次申請,永久使用。?
? ? ??
? ? (2) 接下看看合并后的數據格式,?
? ? ?17 01 00 00 50 00 00 8E 72 65 88 82??
? ? ?這是開頭的幾個字節的數據,從數據看就比較直觀了。這個直接是rtmp video message的內容,去掉了messgae頭的。也就是對應的flv文件的?
video tag的body。17 ?1 表示keyframe,7表示AVC 。接下來的字節01是 AVCPacketType,然后是3個字節的CompositionTime,?
然后是4個字節的nalu數據的長度。后面接著的是nalu數據體?
? ? (3) 實現代碼?
? ? ? int nalu_type = tmp_str.data[9]&;0x1f;?
? ? ? if(nalu_type != 5)?
{?
return NGX_ERROR;?
}//先得到nalu type 這里我們只提取I幀,?
? ? ? ???
parse_offset += 5;?
int nalu_len = ntohl(*(unsigned int *)((char *)tmp_str.data + parse_offset));?
//解析nalu數據長度?
? ? ? ???
memcpy(nalu->data + nalu->len,s->mjpeg_info.sps.data,s->mjpeg_info.sps.len);?
nalu->len += s->mjpeg_info.sps.len;//追加sps到幀前面?
memcpy(nalu->data + nalu->len,s->mjpeg_info.pps.data,s->mjpeg_info.pps.len);?
nalu->len += s->mjpeg_info.pps.len;//追加pps到幀前面?
? ??
? memcpy(nalu->data + nalu->len,nalu_head,4);?
nalu->len += 4;//追加nalu 頭到前面 0x00000001?
memcpy(nalu->data + nalu->len,&;tmp_str.data[9],tmp_str.len - 9);?
nalu->len += (tmp_str.len - 9);//加上剛解析出來的nalu數據體?
? ? ? ? 注意:sps和pps也都是一種nalu。?四 如何提取aac音頻的這里就不詳細描述了,與上面類似
更多開源流媒體技術,請關注我們的微信:EasyDarwin?
總結
以上是生活随笔為你收集整理的从nginx-rtmp中提取一帧h264帧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx proxy_cache 缓存
- 下一篇: nginx_rtmp中解析sps和pps