一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放。搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋。明天就是“五一”,放假三天,更开心啦。

  本文实现视频文件的播放是在自己之前写的文章实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 、 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片 的基础上改进合成来完成的。不多种解释,直接上代码,清晰明了。

  1. NSString *path = [[NSBundle mainBundle] pathForResource:@"nwn" ofType:@"mp4"];
  2. const char *filepath= [path UTF8String];
  3.  
  4. av_register_all();
  5. avformat_network_init();
  6. pFormatCtx = avformat_alloc_context();
  7. if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=){
  8. printf("Couldn't open input stream.\n");
  9. exit();
  10. }
  11.  
  12. /*
  13. * av_find_stream_info():ffmpeg版本更新后没有这个函数了,用avformat_find_stream_info这个函数,可以自己看一下版本更新改动
  14. */
  15. // if(av_find_stream_info(pFormatCtx)<0)
  16. if(avformat_find_stream_info(pFormatCtx, NULL) < )
  17. {
  18. printf("Couldn't find stream information.\n");
  19. exit();
  20. }
  21.  
  22. videoindex=-;
  23. for(int i=; i<pFormatCtx->nb_streams; i++)
  24. if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
  25. {
  26. videoindex=i;
  27. break;
  28. }
  29. if(videoindex==-)
  30. {
  31. printf("Didn't find a video stream.\n");
  32. exit();
  33. }
  34. pCodecCtx=pFormatCtx->streams[videoindex]->codec;
  35. pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  36. if(pCodec==NULL)
  37. {
  38. printf("Codec not found.\n");
  39. exit();
  40. }
  41. /*
  42. * avcodec_open():ffmpeg版本更新后没有这个函数了,用avformat_find_stream_info这个函数,可以自己看一下版本更新改动
  43. * avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
  44. */
  45. // if(avcodec_open(pCodecCtx, pCodec)<0)
  46. if(avcodec_open2(pCodecCtx, pCodec, NULL)<)
  47. {
  48. printf("Could not open codec.\n");
  49. exit();
  50. }
  51. AVFrame *pFrame,*pFrameYUV;
  52. pFrame=avcodec_alloc_frame();
  53. pFrameYUV=avcodec_alloc_frame();
  54. uint8_t *out_buffer;
  55. out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)];
  56. avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
  57.  
  58. int ret, got_picture;
  59. int y_size = pCodecCtx->width * pCodecCtx->height;
  60.  
  61. AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));
  62. av_new_packet(packet, y_size);
  63.  
  64. printf("video infomation:\n");
  65. av_dump_format(pFormatCtx,,filepath,);
  66.  
  67. while(av_read_frame(pFormatCtx, packet)>=)
  68. {
  69. if(packet->stream_index==videoindex)
  70. {
  71. ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
  72. if(ret < )
  73. {
  74. printf("Decode Error.\n");
  75. exit();
  76. }
  77. if(got_picture)
  78. {
  79. char *buf = (char *)malloc(pFrame->width * pFrame->height * / );
  80.  
  81. AVPicture *pict;
  82. int w, h;
  83. char *y, *u, *v;
  84. pict = (AVPicture *)pFrame;//这里的frame就是解码出来的AVFrame
  85. w = pFrame->width;
  86. h = pFrame->height;
  87. y = buf;
  88. u = y + w * h;
  89. v = u + w * h / ;
  90.  
  91. for (int i=; i<h; i++)
  92. memcpy(y + w * i, pict->data[] + pict->linesize[] * i, w);
  93. for (int i=; i<h/; i++)
  94. memcpy(u + w / * i, pict->data[] + pict->linesize[] * i, w / );
  95. for (int i=; i<h/; i++)
  96. memcpy(v + w / * i, pict->data[] + pict->linesize[] * i, w / );
  97.  
  98. [myview setVideoSize:pFrame->width height:pFrame->height];
  99. [myview displayYUV420pData:buf width:pFrame->width height:pFrame->height]; //利用OpenGLES渲染YUV
  100. free(buf);
  101. }
  102. }
  103. av_free_packet(packet);
  104. }
  105. delete[] out_buffer;
  106. av_free(pFrameYUV);
  107. avcodec_close(pCodecCtx);
  108. avformat_close_input(&pFormatCtx);

  本周的学习任务完成啦,写完这篇博客就下班回家,哈哈。五一长假,我要休息下,列出自己下一步的学习计划。下周我想做的是本地音频文件解码播放,以及本地视频文件中音频与视频同步播放。现在所做的都是本地音视频文件的处理,因为本地文件处理起来方便一些,这也让自己学起来也快速一些。关于网络音视频实时流的同步与播放,这个涉及的内容就要复杂一些了,有效学习+时间规划,我肯定能玩透播放器的开发。

  本文完整工程 FFmpegDecode_OpenGLESRenderYUV 的下载地址为:http://pan.baidu.com/s/1dDvpECh

实战FFmpeg + OpenGLES--iOS平台上视频解码和播放的更多相关文章

  1. 使用Vitamio开发iOS平台上的万能播放器

    迅速了解 Vitamio是干什么的?看官方怎么说: "Vitamio SDK for iOS是Yixia Ltd官方推出的 iOS 平台上使用的软件开发工具包(SDK),为iOS开发人员提供 ...

  2. iOS 平台上常见的安装包有三种,deb、ipa 和 pxl

    前言:目前 iOS 平台上常见的安装包有三种,deb.ipa 和 pxl. 其中 deb 格式是 Debian 系统(包含 Debian 和 Ubuntu )专属安装包格式,配合 APT 软件管理系统 ...

  3. 实战AudioToolbox--在iOS平台上播放音频

    上午看了关于AudioToolbox.framework相关的资料,结合网上的资料对AudioToolbox的基本使用有了整体上的认识,上一篇文章 笔谈AudioToolbox(一) 中提到使用Aud ...

  4. unity 在安卓个IOS平台上 同一个按钮 点击后实现不同的功能

    #if UNITY_IOS UIEventListener.Get(mSprites["Recharge"].gameObject).onClick = OnIOSRecharge ...

  5. mui搜索框在ios平台上点击多次才弹出键盘的解决方法

    今天使用Hbuilder调试手机端时,发现搜索框在安卓系统下,点击一次就可以弹出键盘 但是在iso下非常的不规律,要点击多次 代码实现如下: <div class="mui-input ...

  6. 实战FFmpeg--编译iOS平台使用的FFmpeg库(支持arm64的FFmpeg2.6.2)

    编译环境:Mac OS X 10.10.2 ,Xcode 6.3  iOS SDK 8.3        FFmpeg库的下载地址是 http://www.ffmpeg.org/releases/ . ...

  7. iOS平台在ffmpeg中使用librtmp

    转载请注明出处:http://www.cnblogs.com/fpzeng/p/3202344.html 系统版本:OS X 10.8 一.在iOS平台上交叉编译librtmp librtmp lin ...

  8. (译)cocos2d-x跨android&ios平台开发入门教程

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  9. U3D中IOS平台泛型方法尽少使用

    U3D的IOS最小运行库use micro mscorlib是不包含泛型反射方法的,如FieldType.GetGenericArguments方法.所以尽量少用List而直接使用array. 另外请 ...

随机推荐

  1. Android之WebRTC介绍(二)

    WebRTC提供了点对点之间的通信,但并不意味着WebRTC不需要服务器.暂且不说基于服务器的一些扩展业务,WebRTC至少有两件事必须要用到服务器: 1. 浏览器之间交换建立通信的元数据(信令)必须 ...

  2. Nginx的configure脚本支持选项整理

    在不同版本间,选项可能会有些许变化,请总是使用./configure –help命令来检查当前的选项列表. --prefix=<PATH> #Nginx安装路径.如果没有指定,默认为 /u ...

  3. nginx安装和命令

    1. nginx安装 1.1 mac上安装 brew search nginx brew install nginx 1.2 windows上安装 下载nginx.zip,解压到D盘,发送快捷方式到桌 ...

  4. matlab学习笔记13_3创建函数句柄

    一起来学matlab-matlab学习笔记13函数 13_3 创建函数句柄 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://ww2.mathworks.cn/help ...

  5. 第一次使用markdown

    一级标题 二级标题 三家标题 四级标题 五级标题 六级标题 用两个空格来换行 斜体字 斜体字 加粗字体 加粗字体 斜体加粗字体 斜体加粗字体 无序列表用*或者+或者-: 第一箱 第二项 第三项 第四项 ...

  6. redis启动警告解决

    vim /etc/rc.localecho never > /sys/kernel/mm/transparent_hugepage/enabled加入上面那句到/etc/rc.local,开机启 ...

  7. Idea开发环境中,开发springboot类型的项目,如果只引入parent节点,不添加依赖节点,maven是不会加载springboot的任何依赖的

    在SpringBoot类型的项目中,我本来是要使用pringBoot,创建一个Console项目,我原本在pom.xml中添加paren节点了,天真的认为不需要再添加其他任何依赖了,可是接下来的1个小 ...

  8. AngularJS 常见面试问题

    ng-if 跟 ng-show/hide 的区别有哪些? 第一点区别是,ng-if 在后面表达式为 true 的时候才创建这个 dom 节点,ng-show 是初始时就创建了,用 display:bl ...

  9. 使用Skywalking分布式链路追踪系统

    使用Skywalking分布式链路追踪系统 https://www.cnblogs.com/sunyuliang/p/11424848.html 当我们用很多服务时,各个服务间的调用关系是怎么样的?各 ...

  10. noi openjudge 1768:最大子矩阵

    链接:http://noi.openjudge.cn/ch0406/1768/ 描述已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如 ...