Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# ijkplayer


基于ijkplayer的定制化修改:

1、解决ijkplayer切换音轨失步、爆音问题

2、支持双画面同时渲染

3、支持切换左右声道都有声音输出

4、支持声道切换

5、支持FFmpeg硬件解码

6、支持配置FFmpeg-soft、ijk-MediaCodec、FFmpeg-MediaCodec配置修改

7、默认采用FFmpeg-MediaCodec方案,FFmpeg硬件失败重试FFmpeg-soft方案

8、修复FFmpeg解码时NV12渲染颜色错乱的BUG

9、修复DNS解析相关的bug

10、添加文件加密播放功能

Platform | Build Status
-------- | ------------
Android | [![Build Status](https://travis-ci.org/Bilibili/ci-ijk-ffmpeg-android.svg?branch=master)](https://travis-ci.org/Bilibili/ci-ijk-ffmpeg-android)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public void onItemClick(AdapterView<?> parent, View view, final int position, fi
VideoActivity.intentTo(activity, url, name);
}
});

mAdapter.addItem("http://192.168.1.11:8080/3.mp4","局域网多音轨测试mp4");
mAdapter.addItem("http://crossnat.cn:8080/OK1.mp4","多音轨测试mp4");
mAdapter.addItem("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8", "bipbop basic master playlist");
mAdapter.addItem("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8", "bipbop basic 400x300 @ 232 kbps");
mAdapter.addItem("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", "bipbop basic 640x480 @ 650 kbps");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,12 @@ public IMediaPlayer createPlayer(int playerType) {
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);

if (mSettings.getUsingMediaCodec()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 2);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-avc", 2);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-hevc", 2);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-mpeg4", 2);


if (mSettings.getUsingMediaCodecAutoRotate()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
} else {
Expand Down Expand Up @@ -1067,10 +1072,13 @@ public IMediaPlayer createPlayer(int playerType) {
}
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", 2);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "threads", 4);
//todo(xzl) 设置文件解密密钥
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "mask_str", "osvyBFIL");
ijkMediaPlayer.setPitch(1.0f);
}
mediaPlayer = ijkMediaPlayer;
}
Expand Down
78 changes: 39 additions & 39 deletions android/ijkplayer/ijkplayer-example/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">ijkmediademo</string>
<string name="app_name">播放器测试</string>

<string name="N_A">N/A</string>
<string name="close">Close</string>
<string name="exit">Exit</string>
<string name="sample">Sample</string>
<string name="recent">Recent</string>
<string name="settings">Settings</string>
<string name="tracks">Tracks</string>
<string name="toggle_player">Player</string>
<string name="toggle_render">Render</string>
<string name="toggle_ratio">Scale</string>
<string name="show_info">Info</string>
<string name="vdec">vdec</string>
<string name="fps">fps</string>
<string name="v_cache">v-cache</string>
<string name="a_cache">a-cache</string>
<string name="close">关闭</string>
<string name="exit">退出</string>
<string name="sample">示例</string>
<string name="recent">最近</string>
<string name="settings">设置</string>
<string name="tracks">媒体</string>
<string name="toggle_player">播放器</string>
<string name="toggle_render">渲染</string>
<string name="toggle_ratio">缩放</string>
<string name="show_info">详情</string>
<string name="vdec">视频编码</string>
<string name="fps">帧率</string>
<string name="v_cache">视频缓存</string>
<string name="a_cache">音频缓存</string>
<string name="load_cost">load-cost</string>
<string name="seek_cost">seek_cost</string>
<string name="seek_load_cost">seek_load_cost</string>
<string name="tcp_speed">tcp_speed</string>
<string name="bit_rate">bit_rate</string>
<string name="tcp_speed">网速</string>
<string name="bit_rate">比特率</string>

<string name="media_information">Media Information</string>
<string name="mi_player">Player</string>
<string name="mi_media">Media</string>
<string name="mi_profile_level">Profile level</string>
<string name="mi_pixel_format">Pixel format</string>
<string name="mi_resolution">Resolution</string>
<string name="mi_length">Length</string>
<string name="mi_stream_fmt1">Stream #%d</string>
<string name="mi_type">Type</string>
<string name="mi_language">Language</string>
<string name="mi_codec">Codec</string>
<string name="mi_frame_rate">Frame rate</string>
<string name="mi_bit_rate">Bit rate</string>
<string name="mi_sample_rate">Sample rate</string>
<string name="mi_channels">Channels</string>
<string name="media_information">媒体信息</string>
<string name="mi_player">播放器</string>
<string name="mi_media">媒体</string>
<string name="mi_profile_level">规格</string>
<string name="mi_pixel_format">采样格式</string>
<string name="mi_resolution">分辨率</string>
<string name="mi_length">长度</string>
<string name="mi_stream_fmt1"> #%d</string>
<string name="mi_type">类型</string>
<string name="mi_language">语言</string>
<string name="mi_codec">编解码</string>
<string name="mi_frame_rate">帧率</string>
<string name="mi_bit_rate">比特率</string>
<string name="mi_sample_rate">采样率</string>
<string name="mi_channels">通道数</string>
<string name="mi__selected_video_track">*</string>
<string name="mi__selected_audio_track">*</string>
<string name="mi__selected_subtitle_track">*</string>

<string name="TrackType_video">Video</string>
<string name="TrackType_audio">Audio</string>
<string name="TrackType_subtitle">Subtitle</string>
<string name="TrackType_video">视频</string>
<string name="TrackType_audio">音频</string>
<string name="TrackType_subtitle">字幕</string>
<string name="TrackType_timedtext">Timed text</string>
<string name="TrackType_metadata">Meta data</string>
<string name="TrackType_unknown">Unknown</string>
<string name="TrackType_metadata">元数据</string>
<string name="TrackType_unknown">未知</string>

<string name="VideoView_error_text_invalid_progressive_playback">Invalid progressive playback</string>
<string name="VideoView_error_text_unknown">Unknown</string>
<string name="VideoView_error_button">OK</string>
<string name="VideoView_error_button">好的</string>

<string name="VideoView_ar_aspect_fit_parent">Aspect / Fit parent</string>
<string name="VideoView_ar_aspect_fill_parent">Aspect / Fill parent</string>
Expand All @@ -66,7 +66,7 @@
<string name="VideoView_render_texture_view">Render: TextureView</string>

<string name="VideoView_player_none">Player: None</string>
<string name="VideoView_player_AndroidMediaPlayer">Player: AndroidMediaPlayer</string>
<string name="VideoView_player_AndroidMediaPlayer">Player: 原生播放器</string>
<string name="VideoView_player_IjkMediaPlayer">Player: IjkMediaPlayer</string>
<string name="VideoView_player_IjkExoMediaPlayer">Player: IjkExoMediaPlayer</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,5 @@ interface OnTimedTextListener {
* AndroidMediaPlayer: M:
*/
void setDataSource(IMediaDataSource mediaDataSource);

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
public static final int PROP_FLOAT_VIDEO_DECODE_FRAMES_PER_SECOND = 10001;
public static final int PROP_FLOAT_VIDEO_OUTPUT_FRAMES_PER_SECOND = 10002;
public static final int FFP_PROP_FLOAT_PLAYBACK_RATE = 10003;
public static final int FFP_PROP_FLOAT_PITCH_RATE = 11000;
public static final int FFP_PROP_FLOAT_DROP_FRAME_RATE = 10007;

public static final int FFP_PROP_INT64_SELECTED_VIDEO_STREAM = 20001;
Expand Down Expand Up @@ -140,6 +141,8 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
public static final int FFP_PROP_INT64_TCP_SPEED = 20200;
public static final int FFP_PROP_INT64_LATEST_SEEK_LOAD_DURATION = 20300;
public static final int FFP_PROP_INT64_IMMEDIATE_RECONNECT = 20211;
public static final int FFP_PROP_INT64_CHANNEL_CONFIG = 21000;

//----------------------------------------

@AccessedByNative
Expand All @@ -156,7 +159,7 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
@AccessedByNative
private int mListenerContext;

private SurfaceHolder mSurfaceHolder;
private SurfaceHolder mSurfaceHolder[] = new SurfaceHolder[2];
private EventHandler mEventHandler;
private PowerManager.WakeLock mWakeLock = null;
private boolean mScreenOnWhilePlaying;
Expand All @@ -166,7 +169,7 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
private int mVideoHeight;
private int mVideoSarNum;
private int mVideoSarDen;

private int mSurfaceIndex = 0;
private String mDataSource;

/**
Expand Down Expand Up @@ -254,7 +257,12 @@ private native void _setFrameAtTime(String imgCachePath, long startTime, long en
* Update the IjkMediaPlayer SurfaceTexture. Call after setting a new
* display surface.
*/
private native void _setVideoSurface(Surface surface);
private native void _setVideoSurface(Surface surface,int index);


public void setSurfaceIndex(int idx) {
mSurfaceIndex = idx;
}

/**
* Sets the {@link SurfaceHolder} to use for displaying the video portion of
Expand All @@ -271,17 +279,18 @@ private native void _setFrameAtTime(String imgCachePath, long startTime, long en
*/
@Override
public void setDisplay(SurfaceHolder sh) {
mSurfaceHolder = sh;
mSurfaceHolder[mSurfaceIndex] = sh;
Surface surface;
if (sh != null) {
surface = sh.getSurface();
} else {
surface = null;
}
_setVideoSurface(surface);
_setVideoSurface(surface,mSurfaceIndex);
updateSurfaceScreenOn();
}


/**
* Sets the {@link Surface} to be used as the sink for the video portion of
* the media. This is similar to {@link #setDisplay(SurfaceHolder)}, but
Expand All @@ -307,8 +316,8 @@ public void setSurface(Surface surface) {
DebugLog.w(TAG,
"setScreenOnWhilePlaying(true) is ineffective for Surface");
}
mSurfaceHolder = null;
_setVideoSurface(surface);
mSurfaceHolder[mSurfaceIndex] = null;
_setVideoSurface(surface,mSurfaceIndex);
updateSurfaceScreenOn();
}

Expand Down Expand Up @@ -488,6 +497,7 @@ public void setDataSource(IMediaDataSource mediaDataSource)
_setDataSource(mediaDataSource);
}


public void setAndroidIOCallback(IAndroidIO androidIO)
throws IllegalArgumentException, SecurityException, IllegalStateException {
_setAndroidIOCallback(androidIO);
Expand Down Expand Up @@ -566,7 +576,7 @@ public void setWakeMode(Context context, int mode) {
@Override
public void setScreenOnWhilePlaying(boolean screenOn) {
if (mScreenOnWhilePlaying != screenOn) {
if (screenOn && mSurfaceHolder == null) {
if (screenOn && mSurfaceHolder[0] == null && mSurfaceHolder[1] == null) {
DebugLog.w(TAG,
"setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder");
}
Expand All @@ -589,8 +599,11 @@ private void stayAwake(boolean awake) {
}

private void updateSurfaceScreenOn() {
if (mSurfaceHolder != null) {
mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
if (mSurfaceHolder[0] != null) {
mSurfaceHolder[0].setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
}
if (mSurfaceHolder[1] != null) {
mSurfaceHolder[1].setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
}
}

Expand Down Expand Up @@ -754,6 +767,15 @@ public float getSpeed(float speed) {
return _getPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, .0f);
}

public void setPitch(float pitch) {
_setPropertyFloat(FFP_PROP_FLOAT_PITCH_RATE, pitch);
}

public float getPitch(float pitch) {
return _getPropertyFloat(FFP_PROP_FLOAT_PITCH_RATE, .0f);
}


public int getVideoDecoder() {
return (int)_getPropertyLong(FFP_PROP_INT64_VIDEO_DECODER, FFP_PROPV_DECODER_UNKNOWN);
}
Expand All @@ -766,6 +788,14 @@ public float getVideoDecodeFramesPerSecond() {
return _getPropertyFloat(PROP_FLOAT_VIDEO_DECODE_FRAMES_PER_SECOND, 0.0f);
}

public void setChannelConfig(int config) {
_setPropertyLong(FFP_PROP_INT64_CHANNEL_CONFIG, config);
}

public float getChannelConfig() {
return _getPropertyLong(FFP_PROP_INT64_CHANNEL_CONFIG, 0);
}

public long getVideoCachedDuration() {
return _getPropertyLong(FFP_PROP_INT64_VIDEO_CACHED_DURATION, 0);
}
Expand Down
12 changes: 11 additions & 1 deletion config/module-default.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
export COMMON_FF_CFG_FLAGS=
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --prefix=PREFIX"

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-jni "
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=h264_mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=hevc_mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=mpeg2_mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=mpeg4_mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=vp8_mediacodec"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-hwaccel=vp9_mediacodec"

# Licensing options:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-gpl"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-version3"
Expand Down Expand Up @@ -64,7 +73,7 @@ export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-vdpau"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-everything"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-encoders"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-decoders"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-hwaccels"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-hwaccels"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-muxers"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-demuxers"
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-parsers"
Expand All @@ -78,6 +87,7 @@ export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-iconv"
# ...

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=async"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-linux-perf"

# Advanced options (experts only):
# export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --cross-prefix=${FF_CROSS_PREFIX}-"
Expand Down
2 changes: 1 addition & 1 deletion config/module.sh
8 changes: 4 additions & 4 deletions ijkmedia/ijkplayer/android/ijkplayer_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,23 @@ IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*))
return NULL;
}

void ijkmp_android_set_surface_l(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface)
void ijkmp_android_set_surface_l(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface,jint index)
{
if (!mp || !mp->ffplayer || !mp->ffplayer->vout)
return;

SDL_VoutAndroid_SetAndroidSurface(env, mp->ffplayer->vout, android_surface);
SDL_VoutAndroid_SetAndroidSurface(env, mp->ffplayer->vout, android_surface,index);
ffpipeline_set_surface(env, mp->ffplayer->pipeline, android_surface);
}

void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface)
void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface,jint index)
{
if (!mp)
return;

MPTRACE("ijkmp_set_android_surface(surface=%p)", (void*)android_surface);
pthread_mutex_lock(&mp->mutex);
ijkmp_android_set_surface_l(env, mp, android_surface);
ijkmp_android_set_surface_l(env, mp, android_surface,index);
pthread_mutex_unlock(&mp->mutex);
MPTRACE("ijkmp_set_android_surface(surface=%p)=void", (void*)android_surface);
}
Expand Down
2 changes: 1 addition & 1 deletion ijkmedia/ijkplayer/android/ijkplayer_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct ijkmp_android_media_format_context {
// ref_count is 1 after open
IjkMediaPlayer *ijkmp_android_create(int(*msg_loop)(void*));

void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface);
void ijkmp_android_set_surface(JNIEnv *env, IjkMediaPlayer *mp, jobject android_surface,jint index);
void ijkmp_android_set_volume(JNIEnv *env, IjkMediaPlayer *mp, float left, float right);
int ijkmp_android_get_audio_session_id(JNIEnv *env, IjkMediaPlayer *mp);
void ijkmp_android_set_mediacodec_select_callback(IjkMediaPlayer *mp, bool (*callback)(void *opaque, ijkmp_mediacodecinfo_context *mcc), void *opaque);
Expand Down
Loading