C#使用FFmpeg的总结

上篇文章提到FFmpeg解决项目中视频和语音问题,说道C#和FFmpeg不得不提的2个类库。

1、Xabe.FFmpeg

简单查看了下源码和demo,发现基于ffmpeg.exe的命令行参数进行处理。

2、FFmpeg.AutoGen

把C语言对外API和类型翻译成C#的API和对象。

看了一下这个源码生成,其中使用了CppSharp来生成g.cs的文件,然后在编译g.cs文件。

这2类库进行对比,第一个相对简单,第二个处理相对复杂,当然功能也强大。

最终选择FFmpeg.AutoGen 通过API方式灵活度更好,能满足自己的个性需求(推流要实现暂停和继续推流功能)。

FFmpeg.AutoGen源码不是每个版本都保留github上,最好克隆到自己项目中,不同版本的API差别还是有很大,稳定一个版本后即使有小问题,有源代码可以自己修改一下。

项目中手机和电脑视频采用的是rtmp方式推流,现在自己总结一下。

开始说只需要视频,当时就网上搜到一篇文章,在这个基础稍微整理改进一下交给客户。然而没有过多久提出新需,需要显示声音,为了解决这个问题花费不少时间

解决方式记录如下:

一、使用ffplay.exe播放声音,一直报错就没有达到效果。

二、使用VLC,.Net里面有个VLC.DotNet。

  经测试能正常播放视频和语音,但是播放rtmp声音延迟7秒,各种参数设置无效,随着播放时间加长延迟更严重,基本无法正常使用。 另外在观看视频时候 随时需要保存到本地,还需要单独请求地址,明显不符合要求。

三、在播放视频基础上,使用Sdl2.Net播放声音,死活没有效果 。

四、参考网络C++代码,写C++动态库让C#来调用

C#调用C++代码,先简单总结下后面准备写个博客,有两种常见方式调用 :

1、调用纯粹的C++库里面对外API ,即C#使用[DllImport("Test.dll")]方式。

2、调用托管C++的库,即C#直接引用。C++里面添加一个类调用原始C++的方法,即创建一个类来简单包装一下。

开始用第一种方式调用,就会出现多次调用视频报错问题,改为第二种方式new对象解决了第一种的问题,但又发现好多其他问题, 比如不同操作系统 需要生成不同的dll, 不应该选择debug版本否则在不同电脑表现不一样,最关键的是有些内存没有及时释放,视频10分钟后就崩了,总之对C++了解不多会遇到各种问题,被坑怕了。

五、网上找了一个C++封装的播放器和推流器然后提供给C#使用。

   该播放器是基于ffmpeg来实现的,播放器3万,推流器也是3万,核算一下觉得不是很划算,因为我现在遇到问题仅仅是声音无法播放,而项目也不是很着急还有一段时间,也想挑战一下自己。 

六、主角上场,使用FFmpeg.AutoGen来操作API

  实在没有更好的方法,决定用C#来进行。由于ffmpeg用C#的资料真的太少了,知道肯定比较费劲,想做的完美些就硬着头皮来干。经过一些时间努力实现了这些功能,很自豪的是这个视频播放器延迟特别低,感觉是0延迟如果说有延迟基本也在1秒内左右,比市场上很多播放都快,比如这个著名播放器 PotPlayer。



采用第六种方式后交给客户,客户很满意,然后客户给他们的客户部署在生产环境中运行,客户的客户遇到一个问题苹果手机发送语音,在电脑上播放是娃娃音。测试和开发时都是用安卓手机,因为手机端使用html5开发然后发布成app。想着同样的代码就没有用苹果手机仔细测试。在安卓手机上没有任何问题完美实现功能, 到了苹果手机上就不行,心中一千个擦尼玛,苹果这样坑开发者喜欢搞特殊 。后来发现采样率不一样特别是苹果比较低的采样率(32000)有这个问题,44100和48000没有问题,经过一段时间研究才给解决掉。

后续准备写一些列文章来总结一下基于FFmpeg.AutoGen实现推流和拉流的功能,已经实现的功能主要包括下面

拉流方面:

一、C# FFmpeg播放rtmp视频(Bitmap或者BitmapSource来展示图像)

二、C# FFmpeg使用SDL2方式播放rtmp视频

三、C#FFmpeg使用NAudio方式播放rtmp音频。

四、C#FFmpeg使用SDL2方式播放rtmp音频。

五、C#FFmpeg实现rtmp播放器 NAudio播放声音和(Bitmap或者BitmapSource来展示图像)。

六、C# FFmpeg使用SDL2实现rtmp播放器

七、C#FFmpeg本地mp3,mp4文件播放(两种方式SDL2和NAudio)

八、C#FFmpeg边播放rtmp视频,边保存到本地文件。

拉流播放主要有两个难点

1、播放器播放网络rtmp地址 声音和vb.net教程视频不同步

2、C#FFmpeg播放本地文件,使用NAudio播放声音缓存问题。

 由于本地文件解析很快,缓存清理过快导致播放不完整,不清理缓存容易搞爆内存,比如播放60分钟的mp3文件。 

推流方面:

一、C#FFmpeg使用API推摄像头和麦克风到rtmp远程地址

二、C#FFmpeg使用API推桌面和麦克风到rtmp远程地址

三、C#FFmpeg使用API推本地文件MP4,mkv到c#教程rtmp远程地址.

四、C#FFmpeg使用API边推流预览边保存本地文件

五、C#FFmpeg推流(设备和文件)实现暂停功能

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
FFmpeg.AutoGen库是一个C#封装的FFmpeg库,它可以帮助你在C#应用程序中使用FFmpeg功能。以下是一些使用FFmpeg.AutoGen库的步骤: 1. 下载FFmpeg.AutoGen库 你可以从GitHub上下载FFmpeg.AutoGen库。下载后,将其添加到你的项目中。 2. 导入FFmpeg.AutoGen命名空间 在你的代码中,使用以下语句导入FFmpeg.AutoGen命名空间: ``` using FFmpeg.AutoGen; ``` 3. 初始化FFmpeg使用FFmpeg之前,你需要先初始化它。可以使用以下代码: ``` ffmpeg.av_register_all(); ffmpeg.avcodec_register_all(); ffmpeg.avformat_network_init(); ``` 4. 打开输入文件 使用avformat_open_input函数打开输入文件,例如: ``` AVFormatContext* pFormatContext = null; if (ffmpeg.avformat_open_input(&pFormatContext, inputFile, null, null) != 0) { // 出错处理 } ``` 5. 查找流信息 使用avformat_find_stream_info函数查找流信息,例如: ``` if (ffmpeg.avformat_find_stream_info(pFormatContext, null) < 0) { // 出错处理 } ``` 6. 处理流 处理音视频流,例如: ``` AVCodecContext* pCodecContext = null; int audioStreamIndex = -1; int videoStreamIndex = -1; for (int i = 0; i < pFormatContext->nb_streams; i++) { AVStream* stream = pFormatContext->streams[i]; AVCodecParameters* codecParameters = stream->codecpar; AVCodec* codec = null; if (codecParameters->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO) { audioStreamIndex = i; codec = ffmpeg.avcodec_find_decoder(codecParameters->codec_id); pCodecContext = ffmpeg.avcodec_alloc_context3(codec); ffmpeg.avcodec_parameters_to_context(pCodecContext, codecParameters); if (ffmpeg.avcodec_open2(pCodecContext, codec, null) < 0) { // 出错处理 } } else if (codecParameters->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO) { videoStreamIndex = i; codec = ffmpeg.avcodec_find_decoder(codecParameters->codec_id); pCodecContext = ffmpeg.avcodec_alloc_context3(codec); ffmpeg.avcodec_parameters_to_context(pCodecContext, codecParameters); if (ffmpeg.avcodec_open2(pCodecContext, codec, null) < 0) { // 出错处理 } } else { // 其他流类型 } } ``` 7. 释放资源 在使用FFmpeg后,你需要释放资源。可以使用以下代码: ``` ffmpeg.avcodec_free_context(&pCodecContext); ffmpeg.avformat_close_input(&pFormatContext); ``` 以上是使用FFmpeg.AutoGen库的简单步骤,你可以根据自己的需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值