Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:音频抢占问题,issue-5039update:增加raw video resource的支持 #5071

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RawRes;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.AttributeSet;
Expand All @@ -40,6 +42,7 @@
import android.widget.TextView;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -284,6 +287,27 @@ private void setVideoURI(Uri uri, Map<String, String> headers) {
invalidate();
}

public void setDataSource(FileDescriptor fd) {
openVideo();
requestLayout();
invalidate();
}

protected IMediaDataSource mDataSource;

public void setDataSource(@RawRes int rawId) {
AssetFileDescriptor fd = getResources().openRawResourceFd(rawId);
RawDataSourceProvider sp = new RawDataSourceProvider(fd);
setDataSource(sp);
}

public void setDataSource(IMediaDataSource ds) {
this.mDataSource = ds;
openVideo();
requestLayout();
invalidate();
}

// REMOVED: addSubtitleSource
// REMOVED: mPendingSubtitleTracks

Expand All @@ -296,23 +320,38 @@ public void stopPlayback() {
mHudViewHolder.setMediaPlayer(null);
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(null);

abandonAudioFocus();
}
}

private void requestAudioFocus() {
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
if (am == null) return;
am.requestAudioFocus(null,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}

private void abandonAudioFocus() {
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
if (am == null) return;
am.abandonAudioFocus(null);
}

@TargetApi(Build.VERSION_CODES.M)
private void openVideo() {
if (mUri == null || mSurfaceHolder == null) {
if (mSurfaceHolder == null) {
// not ready for playback just yet, will try again later
return;
}
// we shouldn't clear the target state, because somebody might have
// called start() previously
release(false);

AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
// AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
// am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
requestAudioFocus();

try {
mMediaPlayer = createPlayer(mSettings.getPlayer());
Expand All @@ -332,16 +371,24 @@ private void openVideo() {
mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener);
mMediaPlayer.setOnTimedTextListener(mOnTimedTextListener);
mCurrentBufferPercentage = 0;
String scheme = mUri.getScheme();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
mSettings.getUsingMediaDataSource() &&
(TextUtils.isEmpty(scheme) || scheme.equalsIgnoreCase("file"))) {
IMediaDataSource dataSource = new FileMediaDataSource(new File(mUri.toString()));
mMediaPlayer.setDataSource(dataSource);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
if (mUri == null) {
if (mDataSource == null) {
Log.e("ijkPlayer", "data source is null");
return;
}
mMediaPlayer.setDataSource(mDataSource);
} else {
mMediaPlayer.setDataSource(mUri.toString());
String scheme = mUri.getScheme();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
mSettings.getUsingMediaDataSource() &&
(TextUtils.isEmpty(scheme) || scheme.equalsIgnoreCase("file"))) {
IMediaDataSource dataSource = new FileMediaDataSource(new File(mUri.toString()));
mMediaPlayer.setDataSource(dataSource);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
} else {
mMediaPlayer.setDataSource(mUri.toString());
}
}
bindSurfaceHolder(mMediaPlayer, mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
Expand Down Expand Up @@ -411,7 +458,9 @@ public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNu
IMediaPlayer.OnPreparedListener mPreparedListener = new IMediaPlayer.OnPreparedListener() {
public void onPrepared(IMediaPlayer mp) {
mPrepareEndTime = System.currentTimeMillis();
mHudViewHolder.updateLoadCost(mPrepareEndTime - mPrepareStartTime);
if (mHudViewHolder != null) {
mHudViewHolder.updateLoadCost(mPrepareEndTime - mPrepareStartTime);
}
mCurrentState = STATE_PREPARED;

// Get the capabilities of the player for this stream
Expand Down Expand Up @@ -566,9 +615,9 @@ public boolean onError(IMediaPlayer mp, int framework_err, int impl_err) {
.setPositiveButton(R.string.VideoView_error_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* If we get here, there is no onError listener, so
* at least inform them that the video is over.
*/
/* If we get here, there is no onError listener, so
* at least inform them that the video is over.
*/
if (mOnCompletionListener != null) {
mOnCompletionListener.onCompletion(mMediaPlayer);
}
Expand All @@ -593,7 +642,8 @@ public void onBufferingUpdate(IMediaPlayer mp, int percent) {
@Override
public void onSeekComplete(IMediaPlayer mp) {
mSeekEndTime = System.currentTimeMillis();
mHudViewHolder.updateSeekCost(mSeekEndTime - mSeekStartTime);
if (mHudViewHolder != null)
mHudViewHolder.updateSeekCost(mSeekEndTime - mSeekStartTime);
}
};

Expand Down Expand Up @@ -728,8 +778,7 @@ public void release(boolean cleartargetstate) {
if (cleartargetstate) {
mTargetState = STATE_IDLE;
}
AudioManager am = (AudioManager) mAppContext.getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(null);
abandonAudioFocus();
}
}

Expand Down Expand Up @@ -816,14 +865,21 @@ public void pause() {
}
}
mTargetState = STATE_PAUSED;

abandonAudioFocus();
}

public void suspend() {
release(false);
}

public void resume() {
openVideo();
if (isInPlaybackState()) {
mMediaPlayer.start();
}

requestAudioFocus();
// openVideo();
}

@Override
Expand Down Expand Up @@ -1016,6 +1072,10 @@ public static String getPlayerText(Context context, int player) {
return text;
}

public IMediaPlayer getMediaPlayer() {
return mMediaPlayer;
}

public IMediaPlayer createPlayer(int playerType) {
IMediaPlayer mediaPlayer = null;

Expand All @@ -1033,45 +1093,45 @@ public IMediaPlayer createPlayer(int playerType) {
case Settings.PV_PLAYER__IjkMediaPlayer:
default: {
IjkMediaPlayer ijkMediaPlayer = null;
if (mUri != null) {
ijkMediaPlayer = new IjkMediaPlayer();
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);

if (mSettings.getUsingMediaCodec()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
if (mSettings.getUsingMediaCodecAutoRotate()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0);
}
if (mSettings.getMediaCodecHandleResolutionChange()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0);
}
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);
}

if (mSettings.getUsingOpenSLES()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1);
// if (mUri != null) {
ijkMediaPlayer = new IjkMediaPlayer();
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);

if (mSettings.getUsingMediaCodec()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);
if (mSettings.getUsingMediaCodecAutoRotate()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0);
}

String pixelFormat = mSettings.getPixelFormat();
if (TextUtils.isEmpty(pixelFormat)) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
if (mSettings.getMediaCodecHandleResolutionChange()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", pixelFormat);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 0);
}
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);
}

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);
if (mSettings.getUsingOpenSLES()) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0);
}

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
String pixelFormat = mSettings.getPixelFormat();
if (TextUtils.isEmpty(pixelFormat)) {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
} else {
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", pixelFormat);
}
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);

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

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
// }
mediaPlayer = ijkMediaPlayer;
}
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package tv.danmaku.ijk.media.example.widget.media;

import android.content.res.AssetFileDescriptor;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import tv.danmaku.ijk.media.player.misc.IMediaDataSource;

public class RawDataSourceProvider implements IMediaDataSource {
private AssetFileDescriptor mDescriptor;
private byte[] mMediaBytes;
public RawDataSourceProvider(AssetFileDescriptor descriptor) {
this.mDescriptor = descriptor;
}

@Override
public int readAt(long position, byte[] buffer, int offset, int size) {
if (position + 1 >= mMediaBytes.length) {
return -1;
}
int length;
if (position + size < mMediaBytes.length) {
length = size;
} else {
length = (int) (mMediaBytes.length - position);
if (length > buffer.length)
length = buffer.length;
length--;
}
// 把文件内容copy到buffer中;
System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
return length;
}

@Override
public long getSize() throws IOException {
long length = mDescriptor.getLength();
if (mMediaBytes == null) {
InputStream inputStream = mDescriptor.createInputStream();
mMediaBytes = readBytes(inputStream);
}
return length;
}

@Override
public void close() throws IOException {
if (mDescriptor != null)
mDescriptor.close();
mDescriptor = null;
mMediaBytes = null;
}

//读取文件内容
private byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
}