zoukankan      html  css  js  c++  java
  • ios FFmpeg第一阶段学习总结

    前记

    作为一篇没啥内在的文章,我记在博客中主要有两点:1.总结 2.希望刚接触的FFmpeg的朋友能少绕路,希望它起到一定作用。

    在第一阶段学习中,对FFmpeg的精华几乎没有涉及,主要是在ios下实现了一个能播放视频的Demo。Demo目前再声音和图像同步方面做的不够出色,这也是我目前未解决的问题。


    输出图像

    我在编译FFmpeg lib时就使用了iFrameExtractor作为样例。使用一个时钟输出下一帧的图像,然后显示图像就能显示。就这样。。。。

    参考

    [1]iFrameExtractor on GitHub

    [2]An ffmpeg and SDL Tutorial(第一章,第二章)


    声音呢?

    FFmpeg输出声音需要借助平台音频库,针对于ios你可以是用AudioQueue(我用的是这个,我还会告诉你一篇很好的教程),OpenAL。

    参考

    [1]Bear實驗室: iOS用AudioToolbox播放網路收音機 (使用FFmpeg) [Part 2][Part 3]

    [2]《Learing Core Audio》Chapter 4 Recording

    [3]《Learing Core Audio》Chapter 5 PlayBack


    节奏一致

    我们希望我们的图像声音保持同步,iFrameExtractor的作者在自己的WordPress上说明了方法,在GitHub上也有Demo做到了这一点。

    我很奇怪为什么WordPress也得FQ?

    参考

    [1]Programming FFmpeg in iOS (1) (2) (3)

    [2]iOSFFmpeg-master on GitHub

    总结

    其实实现大自同步并不难,我是说“大自”,好吧,其实我现在也知道大自同步。下面我来说说我的实现:

    第一点:如果你同时播放声音和图片,你会发现图片总是跑在音乐的前面,所以我们得将解码得到的图片存起来,减慢它的节奏。

    第二点:你得知道pts,dts。pts =Presentation timestamp in AVStream->time_base units;我们将使用AVPacket中的pts,它意味着这个Frame也就是图片应该在什么时候显示在屏幕上。与主时钟同步需要将pts装换成second。

    1 double _second = pReadPkt.pts * av_q2d(pFormatCtx->streams[VideoStreamIndex]->time_base);
     1 //程序主时钟
     2 -(void)refreshCurrentTime{
     3     if (pCurrentTime){
     4         [pCurrentTime release];
     5         pCurrentTime = nil;
     6     }
     7     if (!pCurrentTime){
     8         pCurrentTime = [[NSDate date]retain];
     9     }
    10 }
    11 
    12 -(void)loopVideoOutput:(NSTimer *)timer {
    13     
    14     
    15     NSTimeInterval elapsedTime = [pCurrentTime timeIntervalSinceNow];
    16     pCurrentSecond -= elapsedTime;
    17     [self refreshCurrentTime];
    18 }
    View Code

    综上来看一段伪代码基本上就是参考[1]的奥义了:

     1 尝试策略:
     2 //我缓存的图片的时钟是否小于主时钟
     3     if([self objectAtIndex:0].second < _syncSecond) 
     4 //是的,读取它,并从队列中删除
     5         [self removeobjectAtIndex:0];
     6 //输出图片更新
     7         poutImage = obj[0];
     8     else
     9 //不,还没轮到它显示 do nothing
    10         [self notRead];
    11  //ImageView更新显示
    12     controller.imageView.image = pOutImage;
    View Code

    这样大自的同步就做到了,你会发现这样的实现图片会快1~2秒,蛋疼。

    在写Demo的时候发现对AVPicture存取的封装好坏会对程序影响很大,参考[2]做出了很好的展示。


    第二阶段的探索

    完全同步并不是接下来的主要方向,在第一阶段我尝试使用过OpenAL做为音频输出,但是得到只有杂音~~~~~这将会是一个棘手的问题。

    当你刚开始在iOS上学习FFmpeg的时候,使用imageView.image = pOutImage是一个很好的选择,除非你一开始就会Opengl,这样你能大大减少代码量。但是Opengl有它的伟大之处,它能输出YUV格式的图片,否则你只能把它变成RGB,然后输出。。。。

    还有一点学习两者,能使你的代码更加通用。。。。因为两者都是跨平台的。

    同步问题却是存在。。。所以解决它。


    最后

    enjoy it!!!


  • 相关阅读:
    图解JavaScript原型和原型链
    hash数组快速查找一个字符串中出现最多的字符,并统计出现的次数
    JS中数组和字符串的方法大全
    用js实现排列组合
    js中一个对象当做参数传递时候?
    用JavaScript按一定格式解析出URL 串中所有的参数
    从Object.definedProperty中看vue的双向数据的绑定
    Uncaught (in promise) TypeError:的错误
    vue之生命周期的一点总结
    原子性和原子性操作
  • 原文地址:https://www.cnblogs.com/asmblog/p/3677413.html
Copyright © 2011-2022 走看看