尝试做一个针对RTMP直播的优化版本, 需求包括秒开, 后台声音, 1s内的延迟.
[有感于国内好多厂家都使用ijkplayer做了修改, 有些已经做出了很多体验很好的版本却没有反馈回社区.]
第一次修改内容: 主要是减少avformat_find_stream_info的时间, 从2~3s降低到0.xs以内. 方式是在avformat_open_input之前设置如下的参数:
if (ffp->iformat_name) {
is->iformat = av_find_input_format(ffp->iformat_name);
}
else if (av_stristart(is->filename, "rtmp", NULL)) {
// by DarwinRie
is->iformat = av_find_input_format("flv"); // 这里是感谢另一位直播同行的分享.
ic->probesize = 4096;
ic->max_analyze_duration = 2000000;
ic->flags |= AVFMT_FLAG_NOBUFFER;
}
这些参数的作用是减少ffmpeg分析的时间. 它会带来一个副作用, 就是可能不能正确的分析完整的流信息. 但是, 对于我们直播应用而言, 流的信息我们是能够具体知道的, 因此, 我在另外一个地方对一些可能缺失的流信息进行的补全:
decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
// by DarwinRie
// if we can't find the width/height from stream, set it with metadata
// coz missing width and height will cause VideoToolBox failed in creation
int width = ffp->is->viddec.avctx->width;
int height = ffp->is->viddec.avctx->height;
if (width == 0 || height == 0) {
width = get_intvalue_from_meta(ic->metadata, "framewidth");
height = get_intvalue_from_meta(ic->metadata, "frameheight");
av_log(NULL, AV_LOG_WARNING, "update video with:%d and height:%d from meta\n", width, height);
ffp->is->viddec.avctx->width = width;
ffp->is->viddec.avctx->height = height;
}
ffp->node_vdec = ffpipeline_open_video_decoder(ffp->pipeline, ffp);
实践发现, 最主要的信息缺失是视频的宽度和高度数据, 它直接影响到VideoToolBox的创建. 于是, 我在flv的meta数据里得到的了视频的宽度和高度数据. 第一次修改尝试就到这里, 延迟还是在2s左右. 没有达到秒开的效果.
2016-11-4 同步原项目代码,添加动态库的编译脚本(demo支持的最低版本从7.0变更到8.0)
动态库的编译方法:
- 打开ios/IJKMediaPlayer/IJKMediaFramework项目,选中UniversalFramework这个target,执行编译
- 编译成功之后在ios/IJKMediaPlayer/IJKMediaFramework/build目录的Debug或者Release目录会生成动态库
- 把动态库加入你的工程,在你的工程的build setting里设置动态库的搜索路径,让它能搜索到动态库所在的路径(可以参考demo工程的设置方法)
- Video player based on ffplay
- Android: MediaPlayer-like
origin/master
Platform | Build Status |
---|---|
Android | |
iOS |
Video player based on ffplay
- Android:
- Gradle
# required
allprojects {
repositories {
jcenter()
}
}
dependencies {
# required, enough for most devices.
compile 'tv.danmaku.ijk.media:ijkplayer-java:0.7.4'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.7.4'
# Other ABIs: optional
compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.7.4'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.7.4'
compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.7.4'
compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.7.4'
# ExoPlayer as IMediaPlayer: optional, experimental
compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.7.4'
}
- iOS
- in coming...
- Common
- Mac OS X 10.11.5
- Android
- NDK r10e
- Android Studio 2.1.3
- Gradle 2.14.1
- iOS
- Xcode 7.3 (7D175)
- HomeBrew
- ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- brew install git
- Common
- remove rarely used ffmpeg components to reduce binary size config/module-lite.sh
- workaround for some buggy online video.
- Android
- platform: API 9~23
- cpu: ARMv7a, ARM64v8a, x86 (ARMv5 is not tested on real devices)
- api: MediaPlayer-like
- video-output: NativeWindow, OpenGL ES 2.0
- audio-output: AudioTrack, OpenSL ES
- hw-decoder: MediaCodec (API 16+, Android 4.1+)
- alternative-backend: android.media.MediaPlayer, ExoPlayer
- iOS
- platform: iOS 6.0~9.3.x
- cpu: armv7, arm64, i386, x86_64, (armv7s is obselete)
- api: MediaPlayer.framework-like
- video-output: OpenGL ES 2.0
- audio-output: AudioQueue, AudioUnit
- hw-decoder: VideoToolbox (iOS 8+)
- alternative-backend: AVFoundation.Framework.AVPlayer, MediaPlayer.Framework.MPMoviePlayerControlelr (obselete since iOS 8)
- obsolete platforms (Android: API-8 and below; iOS: pre-6.0)
- obsolete cpu: ARMv5, ARMv6, MIPS (I don't even have these types of devices…)
- native subtitle render
- avfilter support
# install homebrew, git, yasm
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install git
brew install yasm
# add these lines to your ~/.bash_profile or ~/.profile
# export ANDROID_SDK=<your sdk path>
# export ANDROID_NDK=<your ndk path>
# on Cygwin (unmaintained)
# install git, make, yasm
- If you prefer more codec/format
cd config
rm module.sh
ln -s module-default.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
- If you prefer less codec/format for smaller binary size (include hevc function)
cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
- If you prefer less codec/format for smaller binary size (by default)
cd config
rm module.sh
ln -s module-lite.sh module.sh
cd android/contrib
# cd ios
sh compile-ffmpeg.sh clean
- For Ubuntu/Debian users.
# choose [No] to use bash
sudo dpkg-reconfigure dash
- If you'd like to share your config, pull request is welcome.
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.7.4
./init-android.sh
cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
cd ..
./compile-ijk.sh all
# Android Studio:
# Open an existing Android Studio project
# Select android/ijkplayer/ and import
#
# define ext block in your root build.gradle
# ext {
# compileSdkVersion = 23 // depending on your sdk version
# buildToolsVersion = "23.0.0" // depending on your build tools version
#
# targetSdkVersion = 23 // depending on your sdk version
# }
#
# If you want to enable debugging ijkplayer(native modules) on Android Studio 2.2+: (experimental)
# sh android/patch-debugging-with-lldb.sh armv7a
# Install Android Studio 2.2(+)
# Preference -> Android SDK -> SDK Tools
# Select (LLDB, NDK, Android SDK Build-tools,Cmake) and install
# Open an existing Android Studio project
# Select android/ijkplayer
# Sync Project with Gradle Files
# Run -> Edit Configurations -> Debugger -> Symbol Directories
# Add "ijkplayer-armv7a/.externalNativeBuild/ndkBuild/release/obj/local/armeabi-v7a" to Symbol Directories
# Run -> Debug 'ijkplayer-example'
# if you want to reverse patches:
# sh patch-debugging-with-lldb.sh reverse armv7a
#
# Eclipse: (obselete)
# File -> New -> Project -> Android Project from Existing Code
# Select android/ and import all project
# Import appcompat-v7
# Import preference-v7
#
# Gradle
# cd ijkplayer
# gradle
git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios
cd ijkplayer-ios
git checkout -B latest k0.7.4
./init-ios.sh
cd ios
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
# Demo
# open ios/IJKMediaDemo/IJKMediaDemo.xcodeproj with Xcode
#
# Import into Your own Application
# Select your project in Xcode.
# File -> Add Files to ... -> Select ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj
# Select your Application's target.
# Build Phases -> Target Dependencies -> Select IJKMediaFramework
# Build Phases -> Link Binary with Libraries -> Add:
# IJKMediaFramework.framework
#
# AudioToolbox.framework
# AVFoundation.framework
# CoreGraphics.framework
# CoreMedia.framework
# CoreVideo.framework
# libbz2.tbd
# libz.tbd
# MediaPlayer.framework
# MobileCoreServices.framework
# OpenGLES.framework
# QuartzCore.framework
# UIKit.framework
# VideoToolbox.framework
#
# ... (Maybe something else, if you get any link error)
#
- Please do not send e-mail to me. Public technical discussion on github is preferred.
- 请尽量在 github 上公开讨论技术问题,不要以邮件方式私下询问,恕不一一回复。
Copyright (C) 2013-2016 Zhang Rui <[email protected]>
Licensed under LGPLv2.1 or later
ijkplayer required features are based on or derives from projects below:
- LGPL
- zlib license
- BSD-style license
- ISC license
android/ijkplayer-exo is based on or derives from projects below:
- Apache License 2.0
android/example is based on or derives from projects below:
- GPL
- android-ndk-profiler (not included by default)
ios/IJKMediaDemo is based on or derives from projects below:
- Unknown license
ijkplayer's build scripts are based on or derives from projects below:
ijkplayer is licensed under LGPLv2.1 or later, so itself is free for commercial use under LGPLv2.1 or later
But ijkplayer is also based on other different projects under various licenses, which I have no idea whether they are compatible to each other or to your product.
IANAL, you should always ask your lawyer for these stuffs before use it in your product.