FFmpeg视音频分离器----向雷神学习

news/2024/6/3 16:54:34 标签: ffmpeg, 学习, 音视频

雷神博客地址:https://blog.csdn.net/leixiaohua1020/article/details/39767055

本程序可以将封装格式中的视频码流数据和音频码流数据分离出来。
在该例子中, 将FLV的文件分离得到H.264视频码流文件和MP3
音频码流文件。
注意:
这个是简化版的视音频分离器。与原版的不同在于,没有初始化输出视频流和音频流的AVFormatContext。而是直接将解码后的得到的AVPacket中的的数据通过fwrite()写入文件。这样做的好处是流程比 较简单。坏处是对一些格式的视音频码流是不适用的,比如说FLV/MP4/MKV等格式中的AAC码流(上述封装格式中的AAC的AVPacket中的数据缺失了7字节的ADTS文件头)。

视频源码:

/**
 * 最简单的基于FFmpeg的视音频分离器(简化版)
 * Simplest FFmpeg Demuxer Simple
 *
 * 雷霄骅 Lei Xiaohua
 * leixiaohua1020@126.com
 * 中国传媒大学/数字电视技术
 * Communication University of China / Digital TV Technology
 * http://blog.csdn.net/leixiaohua1020
 *
 * 本程序可以将封装格式中的视频码流数据和音频码流数据分离出来。
 * 在该例子中, 将FLV的文件分离得到H.264视频码流文件和MP3
 * 音频码流文件。
 *
 * 注意:
 * 这个是简化版的视音频分离器。与原版的不同在于,没有初始化输出
 * 视频流和音频流的AVFormatContext。而是直接将解码后的得到的
 * AVPacket中的的数据通过fwrite()写入文件。这样做的好处是流程比
 * 较简单。坏处是对一些格式的视音频码流是不适用的,比如说
 * FLV/MP4/MKV等格式中的AAC码流(上述封装格式中的AAC的AVPacket中
 * 的数据缺失了7字节的ADTS文件头)。
 * 
 *
 * This software split a media file (in Container such as 
 * MKV, FLV, AVI...) to video and audio bitstream.
 * In this example, it demux a FLV file to H.264 bitstream
 * and MP3 bitstream.
 * Note:
 * This is a simple version of "Simplest FFmpeg Demuxer". It is 
 * more simple because it doesn't init Output Video/Audio stream's
 * AVFormatContext. It write AVPacket's data to files directly.
 * The advantages of this method is simple. The disadvantages of
 * this method is it's not suitable for some kind of bitstreams. For
 * example, AAC bitstream in FLV/MP4/MKV Container Format(data in
 * AVPacket lack of 7 bytes of ADTS header).
 *
 */

#include <stdio.h>

#define __STDC_CONSTANT_MACROS

#ifdef _WIN32
//Windows
extern "C"
{
#include "libavformat/avformat.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavformat/avformat.h>
#ifdef __cplusplus
};
#endif
#endif


//'1': Use H.264 Bitstream Filter 
#define USE_H264BSF 1

int main(int argc, char* argv[])
{
	AVFormatContext *ifmt_ctx = NULL;
	AVPacket pkt;
	int ret, i;
	int videoindex=-1,audioindex=-1;
	const char *in_filename  = "cuc_ieschool.flv";//Input file URL
	const char *out_filename_v = "cuc_ieschool.h264";//Output file URL
	const char *out_filename_a = "cuc_ieschool.mp3";

	av_register_all();
	//Input
	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++) {
		if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
			videoindex=i;
		}else if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
			audioindex=i;
		}
	}
	//Dump Format------------------
	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+");  

	/*
	FIX: H.264 in some container format (FLV, MP4, MKV etc.) need 
	"h264_mp4toannexb" bitstream filter (BSF)
	  *Add SPS,PPS in front of IDR frame
	  *Add start code ("0,0,0,1") in front of NALU
	H.264 in some container (MPEG2TS) don't need this BSF.
	*/
#if USE_H264BSF
	AVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb"); 
#endif

	while(av_read_frame(ifmt_ctx, &pkt)>=0){
		if(pkt.stream_index==videoindex){
#if USE_H264BSF
			av_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[videoindex]->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
#endif
			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){
			/*
			AAC in some container format (FLV, MP4, MKV etc.) need to add 7 Bytes
			ADTS Header in front of AVPacket data manually.
			Other Audio Codec (MP3...) works well.
			*/
			printf("Write Audio Packet. size:%d\tpts:%lld\n",pkt.size,pkt.pts);
			fwrite(pkt.data,1,pkt.size,fp_audio);
		}
		av_free_packet(&pkt);
	}

#if USE_H264BSF
	av_bitstream_filter_close(h264bsfc);  
#endif

	fclose(fp_video);
	fclose(fp_audio);

	avformat_close_input(&ifmt_ctx);

	if (ret < 0 && ret != AVERROR_EOF) {
		printf( "Error occurred.\n");
		return -1;
	}
	return 0;
}



SourceForge:https://sourceforge.net/projects/simplestffmpegformat/
上面链接下载后解压缩,在visual Studio直接打开.sln文件直接可以运行

向雷神学习!!!!!


http://www.niftyadmin.cn/n/5044853.html

相关文章

web性能问题排查--上

web有严重的内存泄漏&#xff0c;因此要进行性能排查并进行优化 web性能问题排查--上 1、如何定位到有内存泄漏2、导致js内存泄露的常见原因&#xff08;开发的时候就要注意&#xff09;2.1 eventBus未销毁2.2 setInterval(定时器)没有销毁2.3 addEventListener2.4 匿名函数&am…

【Excel函数】Vlookup的函数的使用

VLOOKUP(垂直查找)是Microsoft Excel中一种非常有用的函数,用于查找并返回一个特定值所在列的相关信息。它通常用于在大型数据表中查找数据。 以下是VLOOKUP函数的基本语法: (lookup_value, table_array, col_index_num, [range_lookup]) lookup_value:这是您要查找的值或…

IP-guard发布新版本4.82.610.0

IP-guard发布新版本4.82.610.0 新版本下载地址&#xff1a;http://www.tec-development.com/down/IPguard/Release/V4/IPguard4.82.0610.0.zip?s6B2D4226740543769BD8CED2D10FC4B1F64F53298624725C4DF687FFE1DEAC61 新版本升级地址&#xff1a;http://www.tec-development.c…

csa从初阶到大牛(训练题1)

使用普通账户新建如下结构的2个目录&#xff1a; ~/t1/t2/t3/t4&#xff0c;~/m1/m2/m3/m4,并显示t1目录的详细信息&#xff0c;将/etc/passwd文件拷贝到~/t1/t2/t3目录下面&#xff0c;将~/t1/下面的内容拷贝到~/m1/m2/m/3/m4目录下面,最后删除~/t1/t2/t3下面的目录 # 创建目…

【2023全新保姆级教图文教程】三分钟快速安装好Anacaonda3+Pycharm运行Python

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

为什么要使用虚拟机?VMware安装使用

前言 大家好&#xff0c;本文是讲述了为什么需要使用虚拟机、使用虚拟机的好处&#xff0c;以及如何在Windows系统中安装VMware。希望对大家有所帮助~ 目录 前言一、为什么要安装使用虚拟机&#xff1f;1.1、什么是虚拟机&#xff1f;1.2、虚拟机的核心组件1.3、使用虚拟机的好…

elsarticle class not displaying email addresses

See https://tex.stackexchange.com/questions/84573/elsarticle-class-not-displaying-email-addresses

代码随想录算法训练营第三天(C) | ● 203.移除链表元素 ● 707.设计链表 ● 206.反转链表

文章目录 前言一、203.移除链表元素二、707.设计链表三、206.反转链表总结 前言 java版&#xff1a; 代码随想录算法训练营第三天 | 203.移除链表元素&#xff0c;707.设计链表&#xff0c;206.反转链表_愚者__的博客-CSDN博客 C: typedef struct ListNodeT {int val;struc…