008-iOS编译FFmpeg、kxmovie实现视频播放

一、需要工具

1.gas-preprocessor(我们需要编译的ffmpeg所需的脚本文件,下载地址:https://github.com/libav/gas-preprocessor)

2.Yasm

3.FFmpeg-iOS-build-script(下载地址:https://github.com/kewlbear/FFmpeg-iOS-build-script)

4.kxmovie(第三方播放库,下载地址:https://github.com/applexiaohao/kxmovie)

 

二、编译过程

1.下载gas-preprocessor

1)下载好的gas-preprocessor解压后文件内容为:

2)将gas-preprocessor.pl文件复制粘贴到 /usr/sbin/ 目录下,若是根本就不能将这个文件复制到这个路径,我们需要换一个路径,/usr/local/bin/ 目录下

a.如果我们没有在桌面上显示硬盘,我们需要去Finder中勾选硬盘复选框

b.然后,我们还需要在终端中输入指令,显示隐藏文件夹

// 显示隐藏文件夹
defaults write com.apple.finder AppleShowAllFiles Yes && killall Finder
// 不显示隐藏文件夹
defaults write com.apple.finder AppleShowAllFiles No && killall Finder

c.打开目标目录

3)然后为文件开启可执行权限,打开终端输入以下命令行:

chmod 777 /usr/sbin/gas-preprocessor.pl

或者

chmod 777 /usr/local/bin/gas-preprocessor.pl

2.下载yasm

1)在下载yasm之前,我们必须先下载Homebrew(Mac平台的一个包管理工具,提供了许多Mac下没有的Linux工具等)。打开终端,输入一下命令行:

brew

 终端显示一下结果,表示已经安装Homebrew:

如果不是以上结果,则需要安装Homebrew。在终端中输入一下命令下载安装:

ruby -e “$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/master/install](https://raw.githubusercontent.com/Homebrew/install/master/install))”

如需卸载Homebrew,打开终端输入:

brew cleanup

2)下载安装yasm

yasm是一个完全重写的 NASM 汇编。目前,它支持x86和AMD64指令集,接受NASM和气体汇编语法,产出二进制,ELF32 , ELF64 , COFF , Mach - O的( 32和64 ),RDOFF2 ,的Win32和Win64对象的格式,并生成STABS 调试信息的来源,DWARF 2 ,CodeView 8格式。

a.下载yasm

brew install yasm

如果结果显示一下情况,表示安装成功

如果已经安装,会出现一下情况:

但是也可能比较麻烦,已经安装,但是没有关联:

如果出现没有关联这个问题,那么我们不防先卸载yasm,终端输入:

brew remove yasm

结果显示如下,表示卸载成功:

然后再重新安装,终端输入:

brew install yasm

结果显示:

按照以上结果提示,终端输入:

brew link yasm

结果显示:

说明目录下/usr/local/include不是可写的,这就注意啦,我们发现,其实在当前目录下,根本就不存在include文件夹,所以必须先去创建该文件夹,终端输入:

sudo mkdir include

需要输入电脑密码,输密码时时不可见的,输完直接回车即可

然后就是需要将用户设为管理者,终端输入:

sudo chown -R $USER:admin /usr/local/include/

需要输入电脑密码,输密码时时不可见的,输完直接回车即可

再就是需要修改用户权限,终端输入:

chmod 777 /usr/local/include/

终端输入:

brew link --overwrite yasm

结果显示:

同样的问题,路径/usr/local/lib不能写,终端输入:

sudo mkdir /usr/local/lib/

终端输入:

sudo chown -R $USER:admin /usr/local/lib/

终端输入:

brew link --overwrite yasm

到这里我们的yasm关联才做好啦...

b.检测是否安装yasm,终端输入:

brew search yasm

已安装结果显示:

未安装结果显示:

 

3.编译FFmpeg-iOS-build-script,得到我们需要的iOS能够用的ffmpeg库

1)下载解压FFmpeg-iOS-build-script,如下文件夹内容:

2)编译脚本

a.打开脚本文件所在文件路径

cd FFmpeg-iOS-build-script文件夹路径

举个例子,我的放在桌面:

cd /Users/mac02/Desktop/FFmpeg-iOS-build-script-master

b.编译命令

./build-ffmpeg.sh

结果显示:

这个时间可能要等得比较久,等编译完成后,我们发现编译后的文件夹内容有:

 4.添加FFmpeg-iOS、下载kxmovie文件到工程

1)新键一个工程

2)将FFmpeg-iOS拖到项目中

3)下载kxmovie,并且将kxmovie文件夹添加到工程中,添加完毕后的项目结构

除了这些,还需要添加一些类库:

框架:MediaPlayer、CoreAudio、 AudioToolbox、Accelerate、QuartzCore、OpenGLES

系统库:libiconv.tbd、libbz2.tbd、libz.tbd

 

三、总结编译中的错误

1.错误信息:'libavformat/avformat.h' file not found

方法:

错误是由于文件路径不对,需要在Build Settings -> Header Search Paths 添加文件路径:

$(PROJECT_DIR)/RTSP/FFmpeg-iOS/include

2.错误信息:

方法:

这是因为缺少VideoToolbox.framework库,添加这个库即可

3.错误信息:

方法:

此处直接按照它的提示,将 'PIX_FMT_RGB24'改变成'AV_PIX_FMT_RGB24'即可

4.错误信息:

在KxMovieDecoder.h 与KxMovieDecoder.m文件中:

方法:

由于KxMovieDecoder.h缺少头文件#import <UIKit/UIKit.h>,添加上去就好

5.因为是FFmpeg 3.0版本,所以还会出现一些其他问题:

方法:

大概的意思是说在KxMovieDecoder文件里面,有一个方法“decodeFrames: ”,在这个方法里面的"_avpicture_deinterlace"这个方法不能用,armv7结构里面没有这种方法。因此需要找到这个方法直接注释掉即可

6.错误信息:

方法:

添加系统库libbz2.1.0.tbd

7.错误信息:

关于Xcode7的一个问题:

does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64

方法:

关于kxmovie的其他问题可以去它的论坛:kxmovie论坛

 

四、添加代码

#import "KxMovieViewController.h" // 导入头文件
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSString *path = @"http://192.168.2.13/test/1avi.avi";
    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];
}

 

五、具体使用请参考kxmovie工程中:KxMovieExample

1.在这里我先贴出我需要使用的控制器代码

 1 // ViewController.m文件
 2 #import "ViewController.h"
 3 #import "KxMovieViewController.h" // 导入头文件
 4 
 5 @interface ViewController ()
 6 
 7 @end
 8 
 9 @implementation ViewController
10 
11 - (void)viewDidLoad
12 {
13     [super viewDidLoad];
14     
15     self.view.backgroundColor = [UIColor whiteColor];
16     
17     // 创建一个按钮
18     UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
19     btn.frame = CGRectMake(40, 100, self.view.bounds.size.width - 40 * 2, 50);
20     [btn setTitle:@"跳转播放器" forState:UIControlStateNormal];
21     btn.titleLabel.font = [UIFont boldSystemFontOfSize:20];
22     btn.backgroundColor = [UIColor blackColor];
23     btn.tintColor = [UIColor whiteColor];
24     [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
25     [self.view addSubview:btn];
26 }
27 
28 #pragma mark - 点击事件
29 - (void)btnClick:(UIButton *)btn
30 {
31     NSString *path = @"rtsp://admin:rIPC2015@192.168.1.64/vga1";
32     NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
33     parameters[KxMovieParameterMinBufferedDuration] = @(5.0);
34 
35     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
36         parameters[KxMovieParameterDisableDeinterlacing] = @(YES);
37     
38     KxMovieViewController *vc = [KxMovieViewController movieViewControllerWithContentPath:path parameters:parameters];
39     vc.view.backgroundColor = [UIColor yellowColor];
40     [self presentViewController:vc animated:YES completion:nil];
41 }
42 
43 @end

2.遇到的问题

在播放网络摄像头实时监控视频时出现以下错误:

UDP timeout, retrying with TCP

Nonmatching transport in server reply

Could not find codec parameters for stream 0 (Video: h264): unspecified size

Consider increasing the value for the 'analyzeduration' and 'probesize' options

Couldn't find stream information

最终我们只需要将kxmovie中文件KxMovieDecoder.m中以下方法做一下修改

 1 - (kxMovieError)openInput:(NSString *)path
 2 {
 3     AVFormatContext *formatCtx = NULL;
 4     if (_interruptCallback) {
 5         formatCtx = avformat_alloc_context();
 6         
 7         if (!formatCtx)
 8             return kxMovieErrorOpenFile;
 9         
10         AVIOInterruptCB cb = {interrupt_callback, (__bridge void *)(self)};
11         formatCtx->interrupt_callback = cb;
12     }
13     
14     // ********** 修改的代码 **********
15     AVDictionary* options = NULL;
16     av_dict_set(&options, "rtsp_transport", "tcp", 0);
17     if (avformat_open_input(&formatCtx, [path cStringUsingEncoding: NSASCIIStringEncoding], NULL, &options) != 0) {
18         if (formatCtx)
19             avformat_free_context(formatCtx);
20         return kxMovieErrorOpenFile;
21     }
22     // ********** 修改的代码 **********
23     
24     if (avformat_find_stream_info(formatCtx, NULL) < 0) {
25         
26         avformat_close_input(&formatCtx);
27         return kxMovieErrorStreamInfoNotFound;
28     }
29     
30     av_dump_format(formatCtx, 0, [path.lastPathComponent cStringUsingEncoding: NSUTF8StringEncoding], false);
31     
32     _formatCtx = formatCtx;
33     return kxMovieErrorNone;
34 }

 

posted @ 2016-07-12 14:42  Frank9098  阅读(287)  评论(0)    收藏  举报