ffmpeg跨平台播放的实现原理:https://cloud.tencent.com/developer/article/1004561
开源视频播放器:https://github.com/Bilibili/ijkplayer(哔哩哔哩的)、https://github.com/kolyvan/kxmovie、VLC播放器(https://github.com/videolan/vlc)http://www.videolan.org/;
ffmpeg源码:https://github.com/FFmpeg/FFmpeg
参考:https://blog.csdn.net/zwz1984/article/details/82824524
ios:利用FFmpeg-iOS-build-script库编译
ffmpeg编译成静态库iOS:https://www.jianshu.com/p/6e7e494b7c85、https://www.jianshu.com/p/ecfbebadbe55
、https://blog.csdn.net/leixiaohua1020/article/details/47071547
在编译之前先把准备工具做好(其实如果不提前下载,编译脚本中也会下载):下载gas-preprocessor.pl(下载地址:https://github.com/libav/gas-preprocessor),下载homebrew,下载yasm.
下载gas-preprocessor的命令:
sudo git clone https://github.com/libav/gas-preprocessor /usr/local/bin/gas 克隆到本地,可以自己随便剪一个目录,放在任何位置
sudo cp /usr/local/bin/gas/gas-preprocessor.pl /usr/local/bin/gas-preprocessor.pl 拷贝到bin目录下
sudo chmod 777 /usr/local/bin/gas-preprocessor.pl 修改权限
sudo rm -rf /usr/local/bin/gas/ 删除gas目录
下载Homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
下载yasm:
curl http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz -o yasm-1.3.0.gz 下载
tar -zxvf yasm-1.3.0.gz 解压
cd yasm-1.3.0 切换目录
./configure && make -j 4 && sudo make install 编译和运行
步骤:
1.FFmpeg-iOS-build-script 是一个外国人写的自动编译的脚本,脚本则会自动从github中把ffmpeg源码下到本地并开始编译出iOS可用的库,支持各种架构。下载编译脚本:https://github.com/kewlbear/FFmpeg-iOS-build-script
git clone https://github.com/kewlbear/FFmpeg-iOS-build-script.git
2.打开build-ffmpeg.sh脚本中,command+F搜索FF_VERSION,修改版本号;(注意:如果拉取不到小分支,那么就去拉取主分支;如果主分支也拉取不到,那么你就要去看看是否存在这个版本的主分支,FF_VERSION对应的版本号不是乱写上去的,是要去官网查看有哪些版本release了,然后去对应你想要的版本,copy一个版本号到FF_VERSION这里,千万不能随心所欲,写一个不存在的版本。)
3.cd到下载的脚本目录,然后执行编译命令./build-ffmpeg.sh,静静等待,可能时间会很长;最后会输出四个文件夹ffmpeg-4.3.1、FFmpeg-iOS 、scratch、thin ,FFmpeg-iOS中就是需要的头文件和静态库;
编译的时候可能有报错提示:xcrun -sdk iphoneos clang is unable to create an executable file.
解决:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/
创建iOS项目:
1.将FFmpeg-iOS中的 include 和 lib文件夹 拖拽进项目中。
2..要在Link Binary With Libraries 里添加如下库:
- libz.tbd
- libbz2.tbd
- libiconv.tbd
- CoreMedia.framework
- VideoToolbox.framework
- AVFoundation.framework
- AudioToolbox
3.在viewcontroller中引入#import "avformat.h" ;在代码中 写 av_register_all() 然后进行编译,如果没有报错,代表编译成功。
4.ios中调用FFmpeg有两种方法:
(1)使用library库对音视频进行操作,需要手动写C++代码去调用 API 使用FFmpeg。
(2)如果想要使用Tool工具来调用 FFmpg 的话,就是直接通过调用传参的方式执行ffmpeg 命令的话,就需要把以下FFmpeg Tool 相关文件加入到项目中:https://www.jianshu.com/p/299906d4054d、https://www.jianshu.com/p/cdd19047858e
(我们在编译的时候使用了--disable-programs编译选项,因此并不会编译命令行相关的工具。因此,我们需要自己编译相关文件来支持FFmpeg命令行的解析,就是把相关文件导入Xcode中编译)。把ffmpeg-4.3.1文件夹中的fftools中的.c和.h全部拖到Xcode中,(qsv.c这个文件是因特尔中硬解码用的工具,可以不添加);stratch文件夹下各种架构的文件夹下的config.h文件拖入xcode中(在scratch目录每个架构都有一个配置文件 config.h 这个文件比较重要。它表示当前编译的库文件的配置参数);
接下来就是一连串的报错,先在include下的libavutil文件夹下添加thread.h文件(这个文件可以在官网下载FFmpeg,libavutil里面有这个文件),在需要的地方导入#include "pthread.h"
;
ffmpeg.opt.c中注释掉:
{ "videotoolbox_pixfmt", HAS_ARG | OPT_STRING | OPT_EXPERT, { &videotoolbox_pixfmt}, "" },
{ "videotoolbox", videotoolbox_init, HWACCEL_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX },
接下来直接注释掉报错的代码,最后就剩下一下的duplicate错误;
duplicate错误解决:直接改掉函数名
ffmpeg.c中的int main(int argc, char **argv)改成int ffmpegmain(int argc, char **argv);这一个函数修改后要在.h中声明一下.
ffmpeg_opt.c中的void show_help_default(const char *opt, const char *arg);
ffmpeg.c中的const int program_birth_year = 2000;
ffmpeg.c中的const char program_name[] = "ffmpeg";
ffprobe.c中的int main(int argc, char **argv);这一个和第一个的main修改后的函数名不能一样.
问题一:ffmpeg.c的代码中会访问空属性导致程序崩溃:
解决:在ffmpegmain.c中 ffmpeg_cleanup方法,在 term_exit() 前,将各个计数器置零:
nb_filtergraphs=0;
nb_output_files=0;
nb_output_streams=0;
nb_input_files=0;
nb_input_streams=0;
问题二:运行后执行完一条命令后app退出的问题:
解决:方法一:在cmdutils.c中void exit_program(int ret);函数中程序退出exit(ret)改成下面的线程退出 pthread_exit(NULL);
void exit_program(int ret)
{
if (program_exit)
program_exit(ret);
这里可以发个通知:FFMPEG_END;
// exit(ret);//这个是退出程序
pthread_exit(NULL);
}
在xcode项目中使用时,则可以用NSThread来新开一个线程,执行完毕之后,把线程关闭了即可。再使用NSThreadWillExitNotification通知,即可监听线程退出的情况。
[NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:@"detach"];
-(void)demo{
[self ffmpegtest];
// [self ffmpegtesttwo];
// [self ffmpegtestthree];
}
写法一:
-(void)ffmpegtest{
NSString *fromFile = [[NSBundle mainBundle]pathForResource:@"ttt.mov" ofType:nil];
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *toFile = [documentPath stringByAppendingPathComponent:@"tt.mp4"];
NSString *command_str = [NSString stringWithFormat:@"ffmpeg -i %@ %@",fromFile,toFile];
// 分割字符串
NSMutableArray *argv_array = [command_str componentsSeparatedByString:(@" ")].mutableCopy;
// 获取参数个数
int argc = (int)argv_array.count;
// 遍历拼接参数
char **argv = calloc(argc, sizeof(char*));
for(int i=0; i<argc; i++)
{
NSString *codeStr = argv_array[i];
argv_array[i] = codeStr;
argv[i] = (char *)[codeStr UTF8String];
}
ffmpegmain(argc, argv);
}
写法二:
-(void)ffmpegtesttwo{
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *fromFile = [[NSBundle mainBundle]pathForResource:@"ttt.mov" ofType:nil];
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *toFile = [documentPath stringByAppendingPathComponent:@"t.mp4"];
int argc = 4;
char **arguments = calloc(argc, sizeof(char*));
if(arguments != NULL)
{
arguments[0] = "ffmpeg";
arguments[1] = "-i";
arguments[2] = (char *)[fromFile UTF8String];
arguments[3] = (char *)[toFile UTF8String];
if (!ffmpegmain(argc, arguments)) {
NSLog(@"生成成功");
}
}
// });
}
播放:
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
@property (nonatomic, strong) AVPlayerViewController *vc;
dispatch_async(dispatch_get_main_queue(), ^{
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *toFile = [documentPath stringByAppendingPathComponent:@"t.mp4"];
NSURL *webVideoUrl = [NSURL fileURLWithPath:toFile];
self.vc= [[AVPlayerViewController alloc] init];
self.vc.player = [[AVPlayer alloc] initWithURL:webVideoUrl];
[self presentViewController:self.vc animated:YES completion:^{
[self.vc.player play];
}];
});
方法二:这个试了一下没成功;
- 在命令执行完不进行结束线程和进程,只进行 cleanup(这个是结束ffmpeg的意思,并不是清理)。exit_program 函数 ,改为调用 ffmpeg_cleanup 函数就可以了。
注意:因FFmpeg 不支持asset-library://
协议和file://
协议故必须把需要处理的文件导入到沙盒中处理;而且文件前面不能添加其他文件夹路径,
#define DocumentDir [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
#define BundlePath(res) [[NSBundle mainBundle] pathForResource:res ofType:nil]
#define DocumentPath(res) [DocumentDir stringByAppendingPathComponent:res]
build-ffmpeg.sh文件内容
#!/bin/sh
# directories
FF_VERSION="4.3.1"
#FF_VERSION="snapshot-git"
if [[ $FFMPEG_VERSION != "" ]]; then
FF_VERSION=$FFMPEG_VERSION
fi
SOURCE="ffmpeg-$FF_VERSION"
FAT="FFmpeg-iOS"
SCRATCH="scratch"
# must be an absolute path
THIN=`pwd`/"thin"
# absolute path to x264 library
#X264=`pwd`/fat-x264
#FDK_AAC=`pwd`/../fdk-aac-build-script-for-iOS/fdk-aac-ios
CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
--disable-doc --enable-pic"
if [ "$X264" ]
then
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-gpl --enable-libx264"
fi
if [ "$FDK_AAC" ]
then
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-libfdk-aac --enable-nonfree"
fi
# avresample
#CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-avresample"
ARCHS="arm64 armv7 x86_64 i386"
COMPILE="y"
LIPO="y"
DEPLOYMENT_TARGET="8.0"
if [ "$*" ]
then
if [ "$*" = "lipo" ]
then
# skip compile
COMPILE=
else
ARCHS="$*"
if [ $# -eq 1 ]
then
# skip lipo
LIPO=
fi
fi
fi
if [ "$COMPILE" ]
then
if [ ! `which yasm` ]
then
echo 'Yasm not found'
if [ ! `which brew` ]
then
echo 'Homebrew not found. Trying to install...'
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" \
|| exit 1
fi
echo 'Trying to install Yasm...'
brew install yasm || exit 1
fi
if [ ! `which gas-preprocessor.pl` ]
then
echo 'gas-preprocessor.pl not found. Trying to install...'
(curl -L https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl \
-o /usr/local/bin/gas-preprocessor.pl \
&& chmod +x /usr/local/bin/gas-preprocessor.pl) \
|| exit 1
fi
if [ ! -r $SOURCE ]
then
echo 'FFmpeg source not found. Trying to download...'
curl http://www.ffmpeg.org/releases/$SOURCE.tar.bz2 | tar xj \
|| exit 1
fi
CWD=`pwd`
for ARCH in $ARCHS
do
echo "building $ARCH..."
mkdir -p "$SCRATCH/$ARCH"
cd "$SCRATCH/$ARCH"
CFLAGS="-arch $ARCH"
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
then
PLATFORM="iPhoneSimulator"
CFLAGS="$CFLAGS -mios-simulator-version-min=$DEPLOYMENT_TARGET"
else
PLATFORM="iPhoneOS"
CFLAGS="$CFLAGS -mios-version-min=$DEPLOYMENT_TARGET -fembed-bitcode"
if [ "$ARCH" = "arm64" ]
then
EXPORT="GASPP_FIX_XCODE5=1"
fi
fi
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
CC="xcrun -sdk $XCRUN_SDK clang"
# force "configure" to use "gas-preprocessor.pl" (FFmpeg 3.3)
if [ "$ARCH" = "arm64" ]
then
AS="gas-preprocessor.pl -arch aarch64 -- $CC"
else
AS="gas-preprocessor.pl -- $CC"
fi
CXXFLAGS="$CFLAGS"
LDFLAGS="$CFLAGS"
if [ "$X264" ]
then
CFLAGS="$CFLAGS -I$X264/include"
LDFLAGS="$LDFLAGS -L$X264/lib"
fi
if [ "$FDK_AAC" ]
then
CFLAGS="$CFLAGS -I$FDK_AAC/include"
LDFLAGS="$LDFLAGS -L$FDK_AAC/lib"
fi
TMPDIR=${TMPDIR/%\/} $CWD/$SOURCE/configure \
--target-os=darwin \
--arch=$ARCH \
--cc="$CC" \
--as="$AS" \
$CONFIGURE_FLAGS \
--extra-cflags="$CFLAGS" \
--extra-ldflags="$LDFLAGS" \
--prefix="$THIN/$ARCH" \
|| exit 1
make -j3 install $EXPORT || exit 1
cd $CWD
done
fi
if [ "$LIPO" ]
then
echo "building fat binaries..."
mkdir -p $FAT/lib
set - $ARCHS
CWD=`pwd`
cd $THIN/$1/lib
for LIB in *.a
do
cd $CWD
echo lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB 1>&2
lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB || exit 1
done
cd $CWD
cp -rf $THIN/$1/include $FAT
fi
echo Done
脚本注释:
#!/bin/bash
#1.首先:定义下载的库名称
source="ffmpeg-3.4"
#2.其次:定义".h/.mm/.c"文件编译的结果目录
#目录作用:用于保存.h/.m/.c文件编译后的结果.o问加你
cache="cache"
#3.定义".a"静态库保存目录
#pwd命令:表示获取当前目录
staticdir=`pwd`/"lk-ffmpeg-iOS"
#4.添加FFmpeg配置选项->默认配置
#Toolchain options:工具链选项(指定我们需要编译平台CUP架构类型)
#--enable-cross-compile:交叉编译
#Developer options:开发者选项
#--disable-debug:禁止使用调试模式
#Program options选项
#--disable-programs:禁用程序(不允许建立命令行程序)
#Documentation options:文档选项
#--disable--doc:不需要编译文档
#Toolchain options:工具链选项
#--enable-pic:允许建立与位置无关代码
configure_flags="--enable-cross-compile --disable-debug --disable-programs --disable-doc --enable-pic"
#5.定义默认CPU平台架构类型
#arm64 armv7->真机->CPU架构类型
#x86_64 i386->模拟器->CPU架构类型
archs="arm64 x86_64 i386"
#6.指定我们的这个库编译系统版本-iOS系统下的7.0以及以上版本使用这个静态库
targetversion="10.1"
#7.接受命令后输入参数
#动态接受命令输入CPU平台架构类型(输入参数:编译指定的CPU库)
if["$*"]
then
#存在输入参数,也就说:外部指定需要编译CPU架构类型
archs="$*"
fi
#8.安装汇编器->yasm
#判断一下是否存在这个汇编器
#目的:通过软件管理器(Homebrew),然后下载安装(或者更新)汇编器
#一个命令就能够帮助我们完成所有的操作
if [ ! `which yasm` ]
then
#Homebrew:软件管理器
#下载一个软件管理器:安装,卸载,更新,搜索等等...
if [ ! `which brew` ]
then
echo"安装brew"
ruby -e"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" || exit 1
fi
echo"安装yasm"
#成功了
#下载安装这个汇编器
#exit -1 ->安装失败了,那么退出程序
brew install yasm ||exit1
fi
echo "循环编译"
#9.for循环编译FFmpeg静态库
currentdir=`pwd`
forarchin$archs
do
echo"开始编译"
#9.1.创建目录
#在编译结果目录下-创建对应的平台架构类型
mkdir -p"$cache/$arch"
#9.2.进入这个目录
cd"$cache/$arch"
#9.3配置编译CPU架构类型->指定当前编译CPU架构类型
archflags="-arch $arch"
#9.4.判定一下你倒是是编译的模拟器.a静态库,还是真机.a静态库
if [ "$arch" = "i386" -o "$arch" = "x86_64" ]
then
#模拟器
platform="iPhoneSimulator"
#支持最小系统版本->iOS系统
archflags="$archflags -mios-simulator-version-min=$targetversion"
else
#真机(mac,iOS都支持)
platform="iPhoneOS"
#支持最小系统版本->iOS系统
archflags="$archflags -mios-version-min=$targetversion -fembed-bitcode"
#注意:优化处理(可有可无)
#如果架构类型是"arm64",那么
if["$arch"="arm64"]
then
#GNU汇编器(GNU Assembler),简称为GAS
#GASPP->汇编器预处理程序
#解决问题:分段错误
#通俗一点:就是程序运行时,变量访问越界一类的问题
EXPORT="GASPP_FIX_XCODE5=1"
fi
fi
#10.正式编译
#tr命令可以对来自标准输入的字符进行替换,压缩和删除
#'[:upper:]'->将小写转成大写
#'[:lower:]'->将大写转成小写
#将platform->转成大写或者小写
XCRUN_SDK=`echo $platform | tr '[:upper:]' '[:lower:]'`
#编译器->编译平台
CC="xcrun -sdk $XCRUN_SDK clang"
#架构类型->arm64
if [ "$arch" = "arm64" ]
then
#音视频默认一个编译命令
#preprocessor.pl帮助我们编译FFmpeg->arm64位静态库
AS="gas-preprocessor.pl -arch aarch64 -- $CC"
else
#默认编译平台
AS="$CC"
fi
echo"执行到了1"
#目录找到FFmepg编译源代码目录->设置编译配置->编译FFmpeg源码
#--target-os:目录系统->darwin(mac系统早期版本名字)
#darwin:是mac系统,iOS系统祖宗
#--arch:CPU平台架构类型
#--cc:指定编译器类型选项
#--as:汇编程序
#$configure_flags最初配置
#--extra-cflags
#--prefix:静态库输出目录
TMPDIR=${TMPDIR/%\/} $currentdir/$source/configure \
--target-os=darwin \
--arch=$arch \
--cc="$CC"\
--as="$AS"\
$configure_flags \
--extra-cflags="$archflags"\
--extra-ldflags="$archflags"\
--prefix="$staticdir/$arch"\
||exit1
echo"执行了"
#解决问题->分段错误问题
#安装->导出静态库(编译.a静态库)
#执行命令
make -j3 install $EXPORT ||exit1
#回到了我们的脚本文件目录
cd $currentdir
done
以上FFmpeg-iOS集成已经完成;
如果把sdl和ffmpeg一起集成,需要以下操作:
1.把在终端编译好的ffmpeg文件夹中的fftools下的ffplay.c文件拖入到xcode中(有可能通过脚本编译的ffmpeg中没有ffplay.c文件,ffplay必须要有sdl的支持);会报错:把#include <SDL.h>和#include <SDL_thread.h>改成#include "SDL.h"和#include "SDL_thread.h";或者在setting -》header searchpath中加入文件所在的文件夹路径;
2.导入编译好的SDL静态库(注意.a文件和include文件夹都要导入),并且需要导入SDL库所有需要的库文件(参考下面的单独集成SDL);
3.接下来可能会有报错,提示duplicate ***错误,把ffprobe.c文件删除掉(这个文件是分析用的,里面有的方法和ffplay.c中的方法名重复了,所以报错,要么删除,要么修改名称);
4.有两种使用方法:
**方法一:在oc中使用ffplay命令行方法,这一步暂时没成功,但是ffmpeg命令行能成功;
如果要在oc中使用ffplay命令行的话,需要把ffplay.c中int main(int argc, char **argv)修改成
int ffplaymain(int argc, char **argv),是为了防止和xcode工程中的main.m中的main方法重复,
使用前需要 extern int ffplaymain(int argc, char **argv);
if (!ffplaymain(argc, arguments)) {
NSLog(@"播放成功");
}
这一步没有成功,暂时放弃!!!!!!!!!!!!!!!!!!!!
**方法二:直接启动ffplay进行播放,先要把xcode中原来的main.m删除,程序启动就会默认走ffplay.c中的main方法,设置fflpay.c中的static const char *input_filename;(这个是播放的源,比如改成static const char *input_filename="http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8",这个是网络视频流; static const char *input_filename="run.mp4", run.mp4是Xcode本地视频;);运行程序就可以播放了;
一般的ffmpeg和sdl是穿插起来使用的;用sdl去显示ffmppeg
======== 到此SDL和ffmpeg集成完成; =========
ffmpeg和SDL实现播放器:https://www.cnblogs.com/leisure_chn/p/10040202.html
目前主流的视频播放器架构有三种:MPC、MPlayer和VLC;MPC基于DirectShow架构,是Windows系统下元祖级别的播放器;MPCHC(是MPC的继承者,射手播放器架构来自它)有很多创新特性,包括开始融入ffmpeg和支持更多DirectX特性和DXVA等等。mplayer就是linux上媒体播放的元祖;mplayer使用ffmpeg作为解码核心,通过反向工程使之可以调用Windows上的DirectShow Filter DLL,纯C语言开发。VLC基于ffmpeg,是模块化设计,纯c语言编写。
iOS单独集成和使用SDL:
SDL官网:https://www.libsdl.org/
SDL库:下载http://www.libsdl.org/release/
文档:sdl联机文档.http://www.libsdl.org/archives/sdldoc-html.zip 或http://www.libsdl.org/archives/SDLRef.chm
参考:https://blog.csdn.net/qq_29350001/article/details/76113152
详细教程:https://blog.csdn.net/lf426/category_364048_1.html
参考:https://blog.csdn.net/mirage520/article/details/8660298、https://blog.csdn.net/luckypeng/article/details/51290400
SDL编译成ios静态库:
xcode创建一个静态库工程,把下载下来的SDL文件夹中的src文件夹下的文件全部导入到xcode,incude文件夹下的文件全部导入到xcode,然后command+B编译得到不同版本的静态库,左后再合成真机和模拟的静态库.‘
或者打开Xcode-Ios项目,直接运行也能得到相应的静态库.
或者直接在ios项目中再建一个project工程,把src和include文件夹拖到新建的工程中,直接编译新工程,然后在其他project中调用SDL的api了;
步骤:
1.导入上面的静态库;
2.添加库文件:
3.
iOS上sdl使用方法:
1)、官网上下载文件后再docs->readme.ios文档里记载的
4、Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iOS provides
its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iOS produces its user
interface programmatically.
5. Delete the contents of main.m and program your app as a regular SDL program instead.
You may replace main.m with your own main.c, but you must tell Xcode not to use the project
prefix file, as it includes Objective-C code.
需要删除app delegate.h和 .m文件(因为SDL提供自己的UIApplicationDelegate),
删除Main.storyboard和main.m,并在info.plist中删除(其实这些不删除也行,把mian.m
中的代码全部注释掉);重新创建一个.c或者.m文件,文件中必须要有mian函数作为程序入口;如下:
*.m文件
#import <UIKit/UIKit.h>
#import "SDL.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@"SDL运行成功");
return 0;
}
}
具体的使用需要参照官方提供的demo; http://www.libsdl.org/release/
使用SDL显示的视频是显示在SDLWindow上;要是显示在view上需要用到openGL;
注意:
1.SDL要是显示视频的话,需要配合FFmpeg穿插在FFmpeg代码中使用(用SDL_texture承载YUV来显示图像视频),如果要单独使用SDL显示视频,需要像调用图片的方式连续显示图片已达到显示视频的效果(类似于ios中UimageView显示图片数组);
2.官方下载下来的SDL中demo有报错需要修改:SDL提供的demo运行会报错,需要修改苹果账号,如果包CBcentraManager的错误,就需要导入CoreBluetooth.framework,并且要在info.plist中添加蓝牙的权限;
SDL_Window * window = SDL_CreateWindow(NULL, 0, 0, 200,100, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);//一旦设置宽度或高度超过屏幕分辨率.就参数无效,变成屏幕大小窗口.(参考https://blog.csdn.net/w839687571/article/details/50754713)
如何把视频渲染到UIView上;
解码一帧就给纹理,然后渲染出来,循环解码-渲染;
SDL_Delay():调节视频显示的速度,
SDL使用教程:http://tjumyk.github.io/sdl-tutorial-cn/contents.html、http://wiki.libsdl.org/CategoryInit、https://blog.csdn.net/leixiaohua1020/article/details/40701203
实现视频播放的框架:windows的DirectX和Directshow、跨平台的openGL、SDL是对前两者的封装、Metal苹果的图形处理软件;
MacOS使用FFmeg命令行:https://www.jianshu.com/p/cac086219a58
网络测试播放源:
香港卫视直播源:
http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8
CCTV1高清:http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8
CCTV3高清:http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8
CCTV5高清:http://ivi.bupt.edu.cn/hls/cctv5hd.m3u8
CCTV5+高清:http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8
CCTV6高清:http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8
苹果提供的测试源(点播):http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8