[iOS]iOS编译FFmpeg、kxmovie实现视频播放

由于项目中需要播放一段服务器返回的视频,群内大神推荐了kxmovie,初步了解了下,在使用的过程中,遇到很多错误,查阅了一些资料,最后总算完成了一个Demo,现将学习过程记录下来,以备以后使用:

期间,参阅了一些资料,最终找到这篇博文讲的比较详细,一些问题按照其中的方法都得到了解决,在此感谢作者!

之所以又写一篇文章,一是对自己学习的总结,对相关问题的整理;二是每个人都有自己的使用习惯,整理成符合自己习惯的文章,对以后使用也是有很大的好处的;

因为使用了kxmovie开源库,就需要先下载它:github地址,官方demo是无法通过编译的,需要自己编译FFmpeg的相关静态库;

一,编译FFmpeg

在使用中,遇到的第一个问题就是编译FFmpeg,由于是第一次编译这种文件,对我来说开始是有些拒绝的;
kxmovie说明中的Build方法,没有搞清楚怎么使用,网上查了,很多也都没有成功,就只能另寻他法了;
最开始的时候找到了这个文章,感觉写的有点简洁,唯一对我有价值的是这个脚本的github地址:FFmpeg-iOS-build-script,在说明中介绍的使用方法中有几种build的方法,这里我尝试了第一个编译所有的文件:
[iOS]iOS编译FFmpeg、kxmovie实现视频播放_第1张图片
下载这个脚本文件,然后cd到这个脚本文件的目录下:
$ cd /Users/mac/Desktop/FFmpeg-iOS-build-script-master 

然后输入:
$ ./build-ffmpeg.sh

如果输出类似如下信息:
Yasm not found
Homebrew not found. Trying to install...
==> This script will install:
/usr/local/bin/brew
/usr/local/Library/...
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
==> The following directories will be made group writable:
/usr/local/.
/usr/local/bin
==> The following directories will have their owner set to Artron_LQQ:
/usr/local/.
/usr/local/bin
==> The following directories will have their group set to admin:
/usr/local/.
/usr/local/bin

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/. /usr/local/bin

意思说没有安装Yasm,需要下载Yasm,按照最后一句的提示,press RETURN(回车键)继续:
会有如下输出:
WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type "man sudo" for more information.

To proceed, enter your password, or type Ctrl-C to abort.

Password:

这里需要输入你电脑的开机密码,输入过程是不显示任何字符的,输完之后,直接回车即可;
之后,会输出一大串的东西,就是Yasm的下载的过程:

==> /usr/bin/sudo /usr/sbin/chown Artron_LQQ /usr/local/. /usr/local/bin
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/. /usr/local/bin
==> /usr/bin/sudo /bin/mkdir /Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown Artron_LQQ /Library/Caches/Homebrew
==> Downloading and installing Homebrew...
remote: Counting objects: 464, done.
remote: Compressing objects: 100% (421/421), done.
remote: Total 464 (delta 26), reused 270 (delta 17), pack-reused 0
Receiving objects: 100% (464/464), 753.13 KiB | 155.00 KiB/s, done.
Resolving deltas: 100% (26/26), done.
From https://github.com/Homebrew/brew
以下省略N行...

Yasm下载完成后,他会继续执行之前的./build-ffmpeg.sh,开始编译FFmpeg
这需要一些时间,耐心等待,直到输出:

上面省略N行 lipo -create /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/arm64/lib/libavutil.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/armv7/lib/libavutil.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/i386/lib/libavutil.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/x86_64/lib/libavutil.a -output FFmpeg-iOS/lib/libavutil.a lipo -create /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/arm64/lib/libswresample.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/armv7/lib/libswresample.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/i386/lib/libswresample.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/x86_64/lib/libswresample.a -output FFmpeg-iOS/lib/libswresample.a lipo -create /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/arm64/lib/libswscale.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/armv7/lib/libswscale.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/i386/lib/libswscale.a /Users/mac/Desktop/FFmpeg-iOS-build-script-master/thin/x86_64/lib/libswscale.a -output FFmpeg-iOS/lib/libswscale.a Done

即编译完成;在之前的脚本文件夹里会多了几个文件夹,
其中FFmpeg-iOS,就是我们项目需要的.a静态库文件及其头文件

[iOS]iOS编译FFmpeg、kxmovie实现视频播放_第2张图片


二,改错:
把这个文件夹拖进工程,注意路径(后面需要配置路径),最好放在根目录,然后添加kxmovie文件,同样放在根目录下;
添加依赖库:VideoToolbox.framework / libz.tbd / libbz2.tbd / libiconv.tbd ;完成后如下图所示:

[iOS]iOS编译FFmpeg、kxmovie实现视频播放_第3张图片


注意:在添加kxmovie的时候,参考文章中提到,官方最新版3.0会有些问题,给了一个2.8版本的:LOFFmpegSample,可以使用这个demo里的kxmovie,减少些错误!!

这个时候编译的话,会报以下这个错误:
[iOS]iOS编译FFmpeg、kxmovie实现视频播放_第4张图片


'libavutil/avconfig.h' file not found

这个错误就是路径不对导致的,这个时候到Build Setting -->Search Paths --> Header Search Paths 添加文件在项目中的路径
FFmpeg-iOS/include
即:
[iOS]iOS编译FFmpeg、kxmovie实现视频播放_第5张图片

接着又会出现如下错误:
Use of undeclared identifier 'PIX_FMT_RGB24'; did you mean 'AV_PIX_FMT_RGB24'?

直接按照它的提示,将 'PIX_FMT_RGB24'改变成'AV_PIX_FMT_RGB24'就行了。

这些改完后,又出现新的错误:
在KxMovieDecoder.h 与KxMovieDecoder.m文件
1.Expected a type
2.Use of undeclared identifier 'UIImage'

因为KxMovieDecoder.h缺少头文件 #import <UIKit/UIKit.h>,添加上去即可。

如果是FFmpeg 3.0还会出现以下错误信息:
Undefined symbols for architecture armv7:
  "_avpicture_deinterlace", referenced from:
      -[KxMovieDecoder decodeFrames:] in KxMovieDecoder.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
大概的意思是说在KxMovieDecoder文件里面,有一个方法“decodeFrames: ”,在这个方法里面的"_avpicture_deinterlace"这个方法不能用,armv7结构里面没有这种方法。因此需要找到这个方法直接注释掉即可。
//                        avpicture_deinterlace((AVPicture*)_videoFrame,
//                                              (AVPicture*)_videoFrame,
//                                              _videoCodecCtx->pix_fmt,
//                                              _videoCodecCtx->width,
//                                              _videoCodecCtx->height);

FFmpeg 3.0版本,还会出现以下问题
Implicit declaration of function 'avpicture_deinterlace' is invalid in C99

同样将报红的地方直接注释掉即可
//                        avpicture_deinterlace((AVPicture*)_videoFrame,
//                                              (AVPicture*)_videoFrame,
//                                              _videoCodecCtx->pix_fmt,
//                                              _videoCodecCtx->width,
//                                              _videoCodecCtx->height);

此处问题总结,见kxmovie

此时,再编译,基本没有错误了...

三,使用:
使用就比较简单了:
#import "ViewController.h"
#import "KxMovieViewController.h"

@interface ViewController ()

@end

@implementation ViewController


- (void)viewDidAppear:(BOOL)animated {
    NSString *path = @"http://v.jxvdy.com/sendfile/w5bgP3A8JgiQQo5l0hvoNGE2H16WbN09X-ONHPq3P3C1BISgf7C-qVs6_c8oaw3zKScO78I--b0BGFBRxlpw13sf2e54QA";
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
    
    // increase buffering for .wmv, it solves problem with delaying audio frames
    if ([path.pathExtension isEqualToString:@"wmv"])
        parameters[KxMovieParameterMinBufferedDuration] = @(5.0);
    
    // disable deinterlacing for iPhone, because it's complex operation can cause stuttering
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        parameters[KxMovieParameterDisableDeinterlacing] = @(YES);
    
    KxMovieViewController *vc = [KxMovieViewController movieViewControllerWithContentPath:path
                                                                               parameters:parameters];
    [self presentViewController:vc animated:YES completion:nil];

}

前前后后,折腾了近三个小时,总算能够播放视频了;
demo地址:kxmovieDemo

参考资料:
https://github.com/kolyvan/kxmovie
https://github.com/applexiaohao/LOFFmpegSample
https://github.com/kewlbear/FFmpeg-iOS-build-script
http://www.jianshu.com/p/c33f4c96074e/comments/2005066
http://ffmpeg.org/index.html

你可能感兴趣的:(avconfig.h,FFmoeg,kxmovie,libavutil)