基于FFMPEG SDK流媒体开发1---解码媒体文件流信息

简介: 最近项目涉及到流媒体等开发,由于有过开发经验深知其难度所在,没办法只能重新拾起,最新版的SDK被改的一塌糊涂,不过大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的关键。

最近项目涉及到流媒体等开发,由于有过开发经验深知其难度所在,没办法只能重新拾起,最新版的SDK被改的一塌糊涂,不过大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的关键。。

我会把每一天的学习经过,更新到博文上,希望能给更多想学习的人带来帮助,篇尾附上工程     以及最新版本SDK。

FFMPEG被大多数的人命令行来使用,其实在真正的流媒体开发中,要想灵活运用其开发流媒体应用层序,必须使用官方SDK开发  ,实际上我们市面上好多产品

都是基于FFMPEG,比如 XX影音  。。 

FFMPEG官网  http://www.ffmpeg.org/

API地址       http://www.ffmpeg.org/doxygen/trunk/index.html

由于在windows下编译非常痛苦,所以还是推荐大家去直接下载编译好的二进制文件,注意官网上并没有直接完整的开发包,你需要分别取下载Linux或者windows下的

共享库 对于windows下还需要下载 .lib导入库,由于我是windows下 这里我就提供windows下载地址

http://ffmpeg.zeranoe.com/builds/   这个页面可以下载到 动态库和到入库 。。因为FFMPEG已经交由别的组织维护了。。。 在下面这个页面找吧 还有一点就是 既然用人家的东西 记住一定要遵循LGPL或GPL许可证...别给国人丢脸  

人家老外都这么说了 

Donating shows that you benefit from my work and are thankful for the time I spend on it. So if you like my work and would like to see more, feel free to donate, if you can't right now don't worry about it and just enjoy using FFmpeg on Windows. Thank you to everyone who has donated in the past!


具体不废话了,如何配置项目啥的,这都是新手级别的问题,我就不详细说明了 直接上代码加注释     我会提供源代码下载 。。。工程配置好的 大家下载研究就行

// ffmpeg_test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"  

#include <windows.h>
#ifdef _CPPRTTI
extern "C"  
{
#endif
	#include "libavcodec/avcodec.h"  //编解码器
	#include "libavformat/avformat.h" //格式上下文 
	#include "libavformat/avio.h"  //音视频IO
	#include "libavutil/file.h"  //处理文件
#ifdef _CPPRTTI  
};
#endif

void  SetStdClr(WORD wd)
{
	SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),wd );
}

int _tmain(int argc, _TCHAR* argv[])
{   
	//注册所有 编码器  解析器 二进制流过滤器
	 av_register_all();
	 avcodec_register_all();
	 SetStdClr(FOREGROUND_RED |   FOREGROUND_GREEN);
	 AVFormatContext *pContext=NULL;//格式上下文
	 int errNo=0 ;
	 pContext=avformat_alloc_context();
	 //打开输入文件 新接口
	 if(0==avformat_open_input(&pContext,".\\test.mp4",nullptr,NULL)){
		 printf("打开文件输入成功!\n");
	 }else
		 return  0;
	 //从上下文检索流信息
	if(0==avformat_find_stream_info(pContext,NULL))
	{
		printf("获取流信息成功!\n");
	}else
		return 0 ;
	//循环多个流
	 SetStdClr(FOREGROUND_RED |   FOREGROUND_BLUE);
	for (unsigned int i=0;i<pContext->nb_streams;i++)
	{   

		//媒体流 
		AVStream *pStream = pContext->streams[i];
		//帧率信息 为有理数/无理数
		AVRational frame =pStream->r_frame_rate;  

		// 时间比率单位
		AVRational timeBase = pStream->time_base; 
		
		//流的持续时间  比特率
		int64_t duration=   pStream->duration ; 
		printf("媒体持续时间%d\n",duration);
		//获取编码类型
		AVCodecContext *pCodecContext=pStream->codec ;
		//获取 媒体类型
		/************************************************************************/
		/* 
		enum AVMediaType {
		AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATA
		AVMEDIA_TYPE_VIDEO,
		AVMEDIA_TYPE_AUDIO,
		AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuous
		AVMEDIA_TYPE_SUBTITLE,
		AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparse
		AVMEDIA_TYPE_NB
		};
                                                                     */
		/************************************************************************/
		AVMediaType avMediaType=pCodecContext->codec_type;
		//编码器ID
		AVCodecID codecID=pCodecContext->codec_id ;
		if(avMediaType == AVMEDIA_TYPE_AUDIO)
		{
			//如果是视频
			int audioChannels = pCodecContext->channels;
			int samplerate = pCodecContext->sample_rate;
			PixelFormat pixelFormat = pCodecContext->pix_fmt;
			printf("Stream%d音频\n",i);
			printf("音频采样频率%d/%d\n",timeBase.num,timeBase.den);
			printf("音频时间单位%d/%d\n",timeBase.num,timeBase.den);
			printf("音频通道数%d\n",audioChannels);

		}
		else if(avMediaType == AVMEDIA_TYPE_VIDEO)
		{
			//如果是音频
			int videoWidth = pCodecContext->width;
			int videoHeight = pCodecContext->height;
			AVSampleFormat sampleFmt = pCodecContext->sample_fmt;
			printf("Stream%d视频\n",i);
			printf("帧率帧率%d/%d\n",frame.den,frame.num);
			printf("视频时间单位%d/%d\n",timeBase.num,timeBase.den);
			printf("图像宽度:%d\t高度:%d\t%\n",videoWidth,videoHeight);
			printf("图像宽度:%d\t高度:%d\t%\n",videoWidth,videoHeight);
		}
		switch(codecID)
		{
		case  AV_CODEC_ID_AAC:
			printf("编码器FAAC\n");
			break;
		case  AV_CODEC_ID_H264:
			printf("编码器H264\n");
			break;
		}

	}
	//释放上下文环境
	if(!pContext)
	{
		avformat_close_input(&pContext);
	}
	return 0;
}


运行结果如下:



工程下载地址

http://download.csdn.net/detail/yue7603835/8268095



目录
相关文章
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
2127 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
651 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
2064 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
475 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
448 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
977 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
721 1
|
编解码 API 数据安全/隐私保护
FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
【9月更文挑战第21天】本文介绍了如何使用FFmpeg和EasyPusher实现移动端RTSP直播。首先概述了EasyPusher的功能及其API,接着详细描述了安装FFmpeg、获取EasyPusher库、初始化对象、打开输入流、配置推送参数及读取推送帧的具体步骤,并提醒开发者注意网络环境、编码参数和权限管理等问题,以确保直播质量与稳定性。
312 8
|
Android开发 开发者
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
谷歌推出的Transformer,作为Jetpack Media3架构的一部分,助力开发者实现音视频格式转换与编辑。Media3简化了媒体处理流程,提升了定制性和可靠性。Transformer可用于剪辑、添加滤镜等操作,其示例代码可在指定GitHub仓库中找到。要使用Transformer,需在`build.gradle`中添加相关依赖,并按文档编写处理逻辑,最终完成音视频转换任务。具体步骤包括配置剪辑参数、设置空间效果以及监听转换事件等。
491 0
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件