前言
关于音视频的学习已经持续了一年左右,中间因为很多事情总是断断续续的,最近终于可以抽出时间来总结一下,打算连续写几篇博客,包括iOS最简播放器、软解码、硬解码等。
最简iOS播放器使用ffmpeg软解码视频数据,SDL_thread窗口管理,SDL_render渲染视频数据,SDL_audio播放音频数据,SDL_thread管理线程。
正文
一、工具库准备
编译准备ffmpeg和SDL。
- ffmpeg
ffmpeg的编译可以参考我的博客FFmpeg在iOS开发中编译并使用,这里使用的是ffmpeg-3.4.2。
- SDL
- 下载
SDL源代码可以到SDL官网下载SDL2.0,如下图
-
编译
下载好后,解压,在Xcode-iOS目录下打开SDL文件里SDL项目,分别选择模拟器和真机build,生成真机和模拟器的.a库,在products目录下右键libSDL2.a,show in finder显示如下图,Debug-iphoneos和Debug-iphonesimulator下各有一个libSDL2.a.
- 合并
合并模拟器和真机的.a文件,以便在模拟器和真机下都可以使用。
lipo -create 真机build生成的.a文件路径 模拟器build生成的.a文件路径 -output 合并后的路径/合并后的文件名
最后把合并生成的libSDL2.a和头文件放在同一个文件夹下。例如我的:
lipo -create /Users/jusun/Library/Developer/Xcode/DerivedData/SDL-dchfilmmlxomauhaifiahcfggttg/Build/Products/Debug-iphoneos/libSDL2.a /Users/jusun/Library/Developer/Xcode/DerivedData/SDL-dchfilmmlxomauhaifiahcfggttg/Build/Products/Debug-iphonesimulator/libSDL2.a -output /Users/jusun/Desktop/SDL2/libSDL2.a
二、环境配置
- 把两个编译好的库加入到自己的项目,修改两个库的头文件路径:在build setting里搜索Search Path,找到Header Search Paths,可以看到这里的头文件路径是空的,下一行Library Search Paths是正确的Library路径,双击打开,分别复制粘贴到Header Search Paths这一行,并修改
$(PROJECT_DIR)/simple-player/FFmpeg-iOS/lib
为$(PROJECT_DIR)/simple-player/FFmpeg-iOS/include
,同样$(PROJECT_DIR)/simple-player/SDL/lib
修改为$(PROJECT_DIR)/simple-player/SDL/include
,如下图:
- 添加必须的三个依赖库
libz.tbd
libbz2.tbd
libiconv.tbd
- ViewController.m里导入系统库头文件
#import <VideoToolbox/VideoToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <GameController/GameController.h>
#import <CoreMotion/CoreMotion.h>
环境配置成功后的目录结构如下图:
build无报错
,大功告成,环境配置完成。
三、项目构建与改造
- 在/Users/jusun/Downloads/FFmpeg-iOS-build-script-master/ffmpeg-3.4.2/fftools目录下
找到ffplay.c、cmdutils.h、cmdutils.c三个文件拖入项目 - 在/Users/jusun/Downloads/FFmpeg-iOS-build-script-master/scratch/arm64目录下找到config.c文件拖入项目
build项目,cmdutils.h里报错的都注释掉。 - ffplay.c搜索找到
static const char *input_filename
修改为
static const char *input_filename = "http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8"
- 注释掉main.m里的所有代码,就会默认走ffplay.c里的main方法。
最终目录结构如下:
运行项目,如果有弹窗,选择always ignore,就可以正常播放:
四、总结
基于ffmpeg(软解码)和SDL的最简播放器已经完工,但问题很明显,视频显示不在UIView上,而是显示在了SDLWindow上,如何把视频显示到UIView花了我很大一段时间去研究,也因此学习了openGL,下一篇准备使用shader、openGL渲染到UIView、GLKView上总结一篇博客,还有本篇里涉及到解码流程、渲染流程、线程管理、队列管理知识也很多,抽时间再总结一下写一篇博客。
本篇博客我的代码地址。