国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用FFMPEG分離mp4/flv文件中的264視頻和aac音頻

這篇具有很好參考價(jià)值的文章主要介紹了使用FFMPEG分離mp4/flv文件中的264視頻和aac音頻。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

?準(zhǔn)備

ffmpeg 4.4

一個(gè)MP4或flv格式的視頻文件

分離流程

大致分為以下幾個(gè)簡單步驟:

1.使用avformat_open_input 函數(shù)打開文件并初始化結(jié)構(gòu)AVFormatContext

2.查找是否存在音頻和視頻信息

3.構(gòu)建一個(gè)h264_mp4toannexb比特流的過濾器,用來給視頻avpaket包添加頭信息

4.打開2個(gè)輸出文件(音頻, 視頻)

5.循環(huán)讀取視頻文件,并將音視頻分別寫入文件

注意:音頻需要手動(dòng)添加頭信息,沒有提供aac的adts自動(dòng)添加的過濾器

ffmpeg flv h264,ffmpeg,ffmpeg,音視頻,aac

?源碼

#include <stdio.h>
extern "C"
{
#include <libavformat/avformat.h>
}

/* 打印編碼器支持該采樣率并查找指定采樣率下標(biāo) */
static int find_sample_rate_index(const AVCodec* codec, int sample_rate)
{
	const int* p = codec->supported_samplerates;
	int sample_rate_index = -1; //支持的分辨率下標(biāo)
	int count = 0;
	while (*p != 0) {// 0作為退出條件,比如libfdk-aacenc.c的aac_sample_rates
		printf("%s 支持采樣率: %dhz  對應(yīng)下標(biāo):%d\n", codec->name, *p, count);

		if (*p == sample_rate)
			sample_rate_index = count;
		p++;
		count++;
	}
	return sample_rate_index;
}


/// <summary>
/// 給aac音頻數(shù)據(jù)添加adts頭
/// </summary>
/// <param name="header">adts數(shù)組</param>
/// <param name="sample_rate">采樣率</param>
/// <param name="channals">通道數(shù)</param>
/// <param name="prfile">音頻編碼器配置文件(FF_PROFILE_AAC_LOW  定義在 avcodec.h)</param>
/// <param name="len">音頻包長度</param>
void addHeader(char header[], int sample_rate, int channals, int prfile, int len)
{
	

	uint8_t sampleIndex = 0;    
	switch (sample_rate) {
	case 96000: sampleIndex = 0; break;
	case 88200: sampleIndex = 1; break;
	case 64000: sampleIndex = 2; break;
	case 48000: sampleIndex = 3; break;
	case 44100: sampleIndex = 4; break;
	case 32000: sampleIndex = 5; break;
	case 24000: sampleIndex = 6; break;
	case 22050: sampleIndex = 7; break;
	case 16000: sampleIndex = 8; break;
	case 12000: sampleIndex = 9; break;
	case 11025: sampleIndex = 10; break;
	case 8000: sampleIndex = 11; break;
	case 7350: sampleIndex = 12; break;
	default: sampleIndex = 4; break;
	}

	uint8_t audioType = 2;	//AAC LC

	uint8_t channelConfig = 2;	//雙通道

	len += 7;
	//0,1是固定的
	header[0] = (uint8_t)0xff;         //syncword:0xfff                          高8bits
	header[1] = (uint8_t)0xf0;         //syncword:0xfff                          低4bits
	header[1] |= (0 << 3);    //MPEG Version:0 for MPEG-4,1 for MPEG-2  1bit
	header[1] |= (0 << 1);    //Layer:0                                 2bits 
	header[1] |= 1;           //protection absent:1                     1bit
	//根據(jù)aac類型,采樣率,通道數(shù)來配置
	header[2] = (audioType - 1) << 6;            //profile:audio_object_type - 1                      2bits
	header[2] |= (sampleIndex & 0x0f) << 2; //sampling frequency index:sampling_frequency_index  4bits 
	header[2] |= (0 << 1);                             //private bit:0                                      1bit
	header[2] |= (channelConfig & 0x04) >> 2;           //channel configuration:channel_config               高1bit
	//根據(jù)通道數(shù)+數(shù)據(jù)長度來配置
	header[3] = (channelConfig & 0x03) << 6;     //channel configuration:channel_config      低2bits
	header[3] |= (0 << 5);                      //original:0                               1bit
	header[3] |= (0 << 4);                      //home:0                                   1bit
	header[3] |= (0 << 3);                      //copyright id bit:0                       1bit  
	header[3] |= (0 << 2);                      //copyright id start:0                     1bit
	header[3] |= ((len & 0x1800) >> 11);           //frame length:value   高2bits
	//根據(jù)數(shù)據(jù)長度來配置
	header[4] = (uint8_t)((len & 0x7f8) >> 3);     //frame length:value    中間8bits
	header[5] = (uint8_t)((len & 0x7) << 5);       //frame length:value    低3bits
	header[5] |= (uint8_t)0x1f;                    //buffer fullness:0x7ff 高5bits
	header[6] = (uint8_t)0xfc;
}


int main() {
	AVFormatContext* ifmt_ctx = NULL;
	AVPacket pkt;
	int ret, i;
	int videoindex = -1, audioindex = -1;
	const char* in_filename = "D:/測試工程/sound/beautlWorld.mp4";
	const char* out_filename_v = "D:/測試工程/sound/ffmpeg_demo.h264";
	const char* out_filename_a = "D:/測試工程/sound/ffmpeg_demo.aac";

	if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
		printf("Could not open input file.");
		return -1;
	}

	if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
		printf("Failed to retrieve input stream information");
		return -1;
	}

	videoindex = -1;
	for (i = 0; i < ifmt_ctx->nb_streams; i++) { //nb_streams:視音頻流的個(gè)數(shù)
		if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
			videoindex = i;
		else if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
			audioindex = i;
	}

	printf("\nInput Video===========================\n");
	av_dump_format(ifmt_ctx, 0, in_filename, 0);  // 打印信息
	printf("\n======================================\n");

	FILE* fp_audio = fopen(out_filename_a, "wb+");
	FILE* fp_video = fopen(out_filename_v, "wb+");


	AVBSFContext* bsf_ctx = NULL;
	const AVBitStreamFilter* pfilter = av_bsf_get_by_name("h264_mp4toannexb");
	if (pfilter == NULL) {
		printf("Get bsf failed!\n");
	}

	if ((ret = av_bsf_alloc(pfilter, &bsf_ctx)) != 0) {
		printf("Alloc bsf failed!\n");

	}

	ret = avcodec_parameters_copy(bsf_ctx->par_in, ifmt_ctx->streams[videoindex]->codecpar);
	if (ret < 0) {
		printf("Set Codec failed!\n");

	}
	ret = av_bsf_init(bsf_ctx);
	if (ret < 0) {
		printf("Init bsf failed!\n");

	}

	//這里遍歷音頻編碼器打印支持的采樣率,并找到當(dāng)前音頻采樣率所在的下表,用于后面添加adts頭
    //本程序并沒有使用,只是測試,如果為了程序健壯性可以采用此方式
	AVCodec* codec = nullptr;
	codec  = avcodec_find_encoder(ifmt_ctx->streams[audioindex]->codecpar->codec_id);
	int sample_rate_index = find_sample_rate_index(codec, ifmt_ctx->streams[audioindex]->codecpar->sample_rate);
	printf("分辨率數(shù)組下表:%d\n", sample_rate_index);



	while (av_read_frame(ifmt_ctx, &pkt) >= 0) {
		if (pkt.stream_index == videoindex) {

			av_bsf_send_packet(bsf_ctx, &pkt);

			while (true)
			{
				ret = av_bsf_receive_packet(bsf_ctx, &pkt);
				if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
					break;
				else if (ret < 0) {
					printf("Receive Pkt failed!\n");
					break;
				}

				printf("Write Video Packet. size:%d\tpts:%lld\n", pkt.size, pkt.pts);

				fwrite(pkt.data, 1, pkt.size, fp_video);
			}
			
		}
		else if (pkt.stream_index == audioindex) {
			printf("Write Audio Packet. size:%d\tpts:%lld\n", pkt.size, pkt.pts);
			char adts[7] = { 0 };
			addHeader(adts, ifmt_ctx->streams[audioindex]->codecpar->sample_rate, 
				ifmt_ctx->streams[audioindex]->codecpar->channels, 
				ifmt_ctx->streams[audioindex]->codecpar->profile,
				pkt.size);
			fwrite(adts, 1, 7, fp_audio);
			fwrite(pkt.data, 1, pkt.size, fp_audio);
		}
		av_packet_unref(&pkt);
	}

	av_bsf_free(&bsf_ctx);


	fclose(fp_video);
	fclose(fp_audio);

	avformat_close_input(&ifmt_ctx);
	return 0;


	if (ifmt_ctx)
		avformat_close_input(&ifmt_ctx);
	if (fp_audio)
		fclose(fp_audio);
	if (fp_video)
		fclose(fp_video);
	if (bsf_ctx)
		av_bsf_free(&bsf_ctx);
	return -1;
}

小記

1.av_read_frame 就是讀取文件并返回下一幀

2.視頻的頭信息不在avpacket中需要使用bsf過濾器來添加

3.aac音頻頭信息需要手動(dòng)添加文章來源地址http://www.zghlxwxcb.cn/news/detail-617490.html

到了這里,關(guān)于使用FFMPEG分離mp4/flv文件中的264視頻和aac音頻的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • FFmpeg4入門13:h264編碼為mp4

    上一篇將yuv源視頻文件編碼為 *.h264 的由libx264實(shí)現(xiàn)壓縮的文件,將源文件從55M編碼為620KB,但是h264文件只有視頻數(shù)據(jù),而且使用范圍不太廣。那么就需要進(jìn)一步的封裝,在此選用最常用的mp4格式為例。 隨便選一個(gè)mp4格式文件,用FFmpeg4入門4:解析視頻并輸出視頻信息或者ffp

    2023年04月10日
    瀏覽(24)
  • 【音視頻 ffmpeg 學(xué)習(xí)】 RTMP推流 mp4文件

    【音視頻 ffmpeg 學(xué)習(xí)】 RTMP推流 mp4文件

    1.RTMP(實(shí)時(shí)消息傳輸協(xié)議)是Adobe 公司開發(fā)的一個(gè)基于TCP的應(yīng)用層協(xié)議。 2.RTMP協(xié)議中基本的數(shù)據(jù)單元稱為消息(Message)。 3.當(dāng)RTMP協(xié)議在互聯(lián)網(wǎng)中傳輸數(shù)據(jù)的時(shí)候,消息會(huì)被拆分成更小的單元,稱為消息塊(Chunk)。 (1). linux 環(huán)境準(zhǔn)備 安裝nginx 和 rtmp模塊 下載nginx安裝包 下載

    2024年02月03日
    瀏覽(33)
  • 20231005使用ffmpeg旋轉(zhuǎn)MP4視頻

    20231005使用ffmpeg旋轉(zhuǎn)MP4視頻

    20231005使用ffmpeg旋轉(zhuǎn)MP4視頻 2023/10/5 12:21 百度搜搜:ffmpeg 旋轉(zhuǎn)90度 https://zhuanlan.zhihu.com/p/637790915 【FFmpeg實(shí)戰(zhàn)】FFMPEG常用命令行 https://blog.csdn.net/weixin_37515325/article/details/127817057 FFMPEG常用命令行 5.視頻旋轉(zhuǎn) 順時(shí)針旋轉(zhuǎn)90度:ffmpeg -i test.mp4 -vf \\\"transpose=1\\\" out.mp4//順時(shí)針旋轉(zhuǎn)90° 逆時(shí)針

    2024年02月07日
    瀏覽(21)
  • 在ubuntu系統(tǒng)上安裝ffmpeg支持rrweb使用rrvideo對視頻文件轉(zhuǎn)mp4格式遇到的一些問題及解決辦法
  • 用ffmpeg解析mp4文件得到時(shí)長、比特率、音視頻信息

    以下是使用C++語言調(diào)用FFmpeg獲取視頻流和音頻流信息的示例代碼: 上述代碼通過 AVFormatContext 結(jié)構(gòu)體和FFmpeg庫函數(shù) avformat_open_input 、 avformat_find_stream_info 等,獲取MP4文件的視頻流和音頻流信息,并將結(jié)果存儲(chǔ)到 MediaInfo 類中。在實(shí)際應(yīng)用中,可以將上述代碼封裝成一個(gè)函數(shù),

    2024年02月12日
    瀏覽(97)
  • 使用ffmpeg將多個(gè)TS視頻拼接成mp4視頻

    使用ffmpeg將多個(gè)TS視頻拼接成mp4視頻

    點(diǎn)擊下面網(wǎng)址下載對應(yīng)版本安裝 https://ffmpeg.org/download.html ? 下載好之后添加環(huán)境變量 添加成功之后在cmd窗口輸入ffmpeg,顯示如下結(jié)果則為成功? 合并單個(gè)文件或者少量文件時(shí),通過以下命令合并 多個(gè)ts視頻可以編輯一個(gè)txt文檔,file.txt 注意:這里必須是單引號(hào),雙引號(hào)會(huì)報(bào)錯(cuò) 進(jìn)入

    2024年02月11日
    瀏覽(35)
  • Flv格式視頻怎么轉(zhuǎn)MP4?視頻格式轉(zhuǎn)換方法分享

    Flv格式視頻怎么轉(zhuǎn)MP4?視頻格式轉(zhuǎn)換方法分享

    FLV格式的視頻是一種早期的視頻格式,不支持更高的分辨率和比特率,這意味著視頻的清晰度和質(zhì)量受限制,無法很好地保留細(xì)節(jié)和質(zhì)量,這種格式的視頻已經(jīng)逐漸被更高質(zhì)量的視頻格式所替代,例如MP4格式,不僅具有很好的兼容性,編輯起來也很方便,下面教大家?guī)追Nflv轉(zhuǎn)

    2024年02月13日
    瀏覽(98)
  • C# 使用ffmpeg將圖片保存為mp4視頻

    使用 FFmpeg 這個(gè)強(qiáng)大的多媒體處理工具,可以輕松地將一系列圖片轉(zhuǎn)換為一個(gè) MP4 視頻文件。以下是一個(gè)基本的命令行示例來完成這個(gè)任務(wù): 命令參數(shù)說明: -framerate 25 :設(shè)置輸入圖像序列的幀率,這里表示每秒25幀。 -i image-%03d.jpg :指定輸入文件格式,這里的? %03d ?是一個(gè)

    2024年04月27日
    瀏覽(18)
  • OpenCV 報(bào)錯(cuò):FFMPEG: tag 0x34363258/‘X264‘ is not supported with codec id 27 and format ‘mp4 / MP4‘

    首先說一下報(bào)錯(cuò)的地方,是在使用VideoWriter保存視頻時(shí): 出現(xiàn)如下錯(cuò)誤: 經(jīng)過查找網(wǎng)上資料,發(fā)現(xiàn)是cv2.VideoWriter_fourcc()參數(shù)存在問題, 解決方法: 將 修改為: 即可完美解決問題。

    2024年02月07日
    瀏覽(40)
  • Qt/C++音視頻開發(fā)69-保存監(jiān)控pcm音頻數(shù)據(jù)到mp4文件/監(jiān)控錄像/錄像存儲(chǔ)和回放/264/265/aac/pcm等

    用ffmpeg做音視頻保存到mp4文件,都會(huì)遇到一個(gè)問題,尤其是在視頻監(jiān)控行業(yè),就是監(jiān)控?cái)z像頭設(shè)置的音頻是PCM/G711A/G711U,解碼后對應(yīng)的格式是pcm_s16be/pcm_alaw/pcm_mulaw,將這個(gè)原始的音頻流保存到mp4文件是會(huì)報(bào)錯(cuò)的,在調(diào)用avformat_write_header寫文件頭的時(shí)候提示(-22) Invalid argument,

    2024年04月11日
    瀏覽(38)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包