Support ijkplayer - part 5

pull/123/head
FongMi 3 years ago
parent a78261751e
commit 5250bbc99d
  1. 2
      ijkplayer/src/main/AndroidManifest.xml
  2. 10
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/bean/MediaInfo.java
  3. 13
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/bean/TrackAudioInfo.java
  4. 14
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/bean/TrackVideoInfo.java
  5. 73
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/IRenderView.java
  6. 1102
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/IjkVideoView.java
  7. 162
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/MeasureHelper.java
  8. 56
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/MediaPlayerCompat.java
  9. 240
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/SurfaceRenderView.java
  10. 292
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/media/TextureRenderView.java
  11. 128
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/setting/IjkPlayerSetting.java
  12. 71
      ijkplayer/src/main/java/com/lodz/android/mmsplayer/ijk/utils/MediaInfoUtils.java
  13. 1
      ijkplayer/src/main/java/tv/danmaku/ijk/media/player/IjkMediaPlayer.java

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="tv.danmaku.ijk.media.player" />
<manifest package="com.lodz.android.mmsplayer" />

@ -0,0 +1,10 @@
package com.lodz.android.mmsplayer.ijk.bean;
public class MediaInfo {
public String playerName = "";
public String resolution = "";
public String length = "";
public TrackVideoInfo trackVideoInfoBean;
public TrackAudioInfo trackAudioInfoBean;
}

@ -0,0 +1,13 @@
package com.lodz.android.mmsplayer.ijk.bean;
public class TrackAudioInfo {
public String type = "";
public String language = "";
public String codec = "";
public String profileLevel = "";
public String sampleRate = "";
public String channels = "";
public String bitRate = "";
public boolean isSelected;
}

@ -0,0 +1,14 @@
package com.lodz.android.mmsplayer.ijk.bean;
public class TrackVideoInfo {
public String type = "";
public String language = "";
public String codec = "";
public String profileLevel = "";
public String pixelFormat = "";
public String resolution = "";
public String frameRate = "";
public String bitRate = "";
public boolean isSelected;
}

@ -0,0 +1,73 @@
package com.lodz.android.mmsplayer.ijk.media;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import tv.danmaku.ijk.media.player.IMediaPlayer;
public interface IRenderView {
int AR_ASPECT_FIT_PARENT = 0;
int AR_ASPECT_FILL_PARENT = 1;
int AR_ASPECT_WRAP_CONTENT = 2;
int AR_MATCH_PARENT = 3;
int AR_16_9_FIT_PARENT = 4;
int AR_4_3_FIT_PARENT = 5;
View getView();
boolean shouldWaitForResize();
void setVideoSize(int videoWidth, int videoHeight);
void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen);
void setVideoRotation(int degree);
void setAspectRatio(int aspectRatio);
void addRenderCallback(@NonNull IRenderCallback callback);
void removeRenderCallback(@NonNull IRenderCallback callback);
interface ISurfaceHolder {
void bindToMediaPlayer(IMediaPlayer mp);
@NonNull
IRenderView getRenderView();
@Nullable
SurfaceHolder getSurfaceHolder();
@Nullable
Surface openSurface();
@Nullable
SurfaceTexture getSurfaceTexture();
}
interface IRenderCallback {
/**
* @param holder
* @param width could be 0
* @param height could be 0
*/
void onSurfaceCreated(@NonNull ISurfaceHolder holder, int width, int height);
/**
* @param holder
* @param format could be 0
* @param width
* @param height
*/
void onSurfaceChanged(@NonNull ISurfaceHolder holder, int format, int width, int height);
void onSurfaceDestroyed(@NonNull ISurfaceHolder holder);
}
}

@ -0,0 +1,162 @@
package com.lodz.android.mmsplayer.ijk.media;
import android.view.View;
import java.lang.ref.WeakReference;
public final class MeasureHelper {
private final WeakReference<View> mWeakView;
private int mVideoWidth;
private int mVideoHeight;
private int mVideoSarNum;
private int mVideoSarDen;
private int mVideoRotationDegree;
private int mMeasuredWidth;
private int mMeasuredHeight;
private int mCurrentAspectRatio = IRenderView.AR_ASPECT_FIT_PARENT;
public MeasureHelper(View view) {
mWeakView = new WeakReference<>(view);
}
public View getView() {
return mWeakView.get();
}
public void setVideoSize(int videoWidth, int videoHeight) {
mVideoWidth = videoWidth;
mVideoHeight = videoHeight;
}
public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
mVideoSarNum = videoSarNum;
mVideoSarDen = videoSarDen;
}
public void setVideoRotation(int videoRotationDegree) {
mVideoRotationDegree = videoRotationDegree;
}
public void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
int tempSpec = widthMeasureSpec;
widthMeasureSpec = heightMeasureSpec;
heightMeasureSpec = tempSpec;
}
int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec);
int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec);
if (mCurrentAspectRatio == IRenderView.AR_MATCH_PARENT) {
width = widthMeasureSpec;
height = heightMeasureSpec;
} else if (mVideoWidth > 0 && mVideoHeight > 0) {
int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == View.MeasureSpec.AT_MOST && heightSpecMode == View.MeasureSpec.AT_MOST) {
float specAspectRatio = (float) widthSpecSize / (float) heightSpecSize;
float displayAspectRatio;
switch (mCurrentAspectRatio) {
case IRenderView.AR_16_9_FIT_PARENT:
displayAspectRatio = 16.0f / 9.0f;
if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) displayAspectRatio = 1.0f / displayAspectRatio;
break;
case IRenderView.AR_4_3_FIT_PARENT:
displayAspectRatio = 4.0f / 3.0f;
if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) displayAspectRatio = 1.0f / displayAspectRatio;
break;
case IRenderView.AR_ASPECT_FIT_PARENT:
case IRenderView.AR_ASPECT_FILL_PARENT:
case IRenderView.AR_ASPECT_WRAP_CONTENT:
default:
displayAspectRatio = (float) mVideoWidth / (float) mVideoHeight;
if (mVideoSarNum > 0 && mVideoSarDen > 0) displayAspectRatio = displayAspectRatio * mVideoSarNum / mVideoSarDen;
break;
}
boolean shouldBeWider = displayAspectRatio > specAspectRatio;
switch (mCurrentAspectRatio) {
case IRenderView.AR_ASPECT_FIT_PARENT:
case IRenderView.AR_16_9_FIT_PARENT:
case IRenderView.AR_4_3_FIT_PARENT:
if (shouldBeWider) {
width = widthSpecSize;
height = (int) (width / displayAspectRatio);
} else {
height = heightSpecSize;
width = (int) (height * displayAspectRatio);
}
break;
case IRenderView.AR_ASPECT_FILL_PARENT:
if (shouldBeWider) {
height = heightSpecSize;
width = (int) (height * displayAspectRatio);
} else {
width = widthSpecSize;
height = (int) (width / displayAspectRatio);
}
break;
case IRenderView.AR_ASPECT_WRAP_CONTENT:
default:
if (shouldBeWider) {
width = Math.min(mVideoWidth, widthSpecSize);
height = (int) (width / displayAspectRatio);
} else {
height = Math.min(mVideoHeight, heightSpecSize);
width = (int) (height * displayAspectRatio);
}
break;
}
} else if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {
width = widthSpecSize;
height = heightSpecSize;
if (mVideoWidth * height < width * mVideoHeight) {
width = height * mVideoWidth / mVideoHeight;
} else if (mVideoWidth * height > width * mVideoHeight) {
height = width * mVideoHeight / mVideoWidth;
}
} else if (widthSpecMode == View.MeasureSpec.EXACTLY) {
width = widthSpecSize;
height = width * mVideoHeight / mVideoWidth;
if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
height = heightSpecSize;
}
} else if (heightSpecMode == View.MeasureSpec.EXACTLY) {
height = heightSpecSize;
width = height * mVideoWidth / mVideoHeight;
if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
width = widthSpecSize;
}
} else {
width = mVideoWidth;
height = mVideoHeight;
if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
height = heightSpecSize;
width = height * mVideoWidth / mVideoHeight;
}
if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
width = widthSpecSize;
height = width * mVideoHeight / mVideoWidth;
}
}
}
mMeasuredWidth = width;
mMeasuredHeight = height;
}
public int getMeasuredWidth() {
return mMeasuredWidth;
}
public int getMeasuredHeight() {
return mMeasuredHeight;
}
public void setAspectRatio(int aspectRatio) {
mCurrentAspectRatio = aspectRatio;
}
}

@ -0,0 +1,56 @@
package com.lodz.android.mmsplayer.ijk.media;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
import tv.danmaku.ijk.media.player.MediaPlayerProxy;
import tv.danmaku.ijk.media.player.TextureMediaPlayer;
public class MediaPlayerCompat {
public static String getName(IMediaPlayer mp) {
if (mp == null) {
return "null";
} else if (mp instanceof TextureMediaPlayer) {
StringBuilder sb = new StringBuilder("TextureMediaPlayer <");
IMediaPlayer internalMediaPlayer = ((TextureMediaPlayer) mp).getInternalMediaPlayer();
if (internalMediaPlayer == null) {
sb.append("null>");
} else {
sb.append(internalMediaPlayer.getClass().getSimpleName());
sb.append(">");
}
return sb.toString();
} else {
return mp.getClass().getSimpleName();
}
}
public static IjkMediaPlayer getIjkMediaPlayer(IMediaPlayer mp) {
IjkMediaPlayer ijkMediaPlayer = null;
if (mp == null) return null;
if (mp instanceof IjkMediaPlayer) {
ijkMediaPlayer = (IjkMediaPlayer) mp;
} else if (mp instanceof MediaPlayerProxy && ((MediaPlayerProxy) mp).getInternalMediaPlayer() instanceof IjkMediaPlayer) {
ijkMediaPlayer = (IjkMediaPlayer) ((MediaPlayerProxy) mp).getInternalMediaPlayer();
}
return ijkMediaPlayer;
}
public static void selectTrack(IMediaPlayer mp, int stream) {
IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
if (ijkMediaPlayer == null) return;
ijkMediaPlayer.selectTrack(stream);
}
public static void deselectTrack(IMediaPlayer mp, int stream) {
IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
if (ijkMediaPlayer == null) return;
ijkMediaPlayer.deselectTrack(stream);
}
public static int getSelectedTrack(IMediaPlayer mp, int trackType) {
IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
if (ijkMediaPlayer == null) return -1;
return ijkMediaPlayer.getSelectedTrack(trackType);
}
}

@ -0,0 +1,240 @@
package com.lodz.android.mmsplayer.ijk.media;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.ISurfaceTextureHolder;
public class SurfaceRenderView extends SurfaceView implements IRenderView {
private MeasureHelper mMeasureHelper;
public SurfaceRenderView(Context context) {
super(context);
initView(context);
}
public SurfaceRenderView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initView(context);
}
private void initView(Context context) {
mMeasureHelper = new MeasureHelper(this);
mSurfaceCallback = new SurfaceCallback(this);
getHolder().addCallback(mSurfaceCallback);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
@Override
public View getView() {
return this;
}
@Override
public boolean shouldWaitForResize() {
return true;
}
@Override
public void setVideoSize(int videoWidth, int videoHeight) {
if (videoWidth > 0 && videoHeight > 0) {
mMeasureHelper.setVideoSize(videoWidth, videoHeight);
getHolder().setFixedSize(videoWidth, videoHeight);
requestLayout();
}
}
@Override
public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
if (videoSarNum > 0 && videoSarDen > 0) {
mMeasureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen);
requestLayout();
}
}
@Override
public void setVideoRotation(int degree) {
Log.e("", "SurfaceView doesn't support rotation (" + degree + ")!\n");
}
@Override
public void setAspectRatio(int aspectRatio) {
mMeasureHelper.setAspectRatio(aspectRatio);
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMeasureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mMeasureHelper.getMeasuredWidth(), mMeasureHelper.getMeasuredHeight());
}
private static final class InternalSurfaceHolder implements IRenderView.ISurfaceHolder {
private final SurfaceRenderView mSurfaceView;
private final SurfaceHolder mSurfaceHolder;
private InternalSurfaceHolder(@NonNull SurfaceRenderView surfaceView, @Nullable SurfaceHolder surfaceHolder) {
mSurfaceView = surfaceView;
mSurfaceHolder = surfaceHolder;
}
public void bindToMediaPlayer(IMediaPlayer mp) {
if (mp != null) {
if (mp instanceof ISurfaceTextureHolder) {
ISurfaceTextureHolder textureHolder = (ISurfaceTextureHolder) mp;
textureHolder.setSurfaceTexture(null);
}
mp.setDisplay(mSurfaceHolder);
}
}
@NonNull
@Override
public IRenderView getRenderView() {
return mSurfaceView;
}
@Nullable
@Override
public SurfaceHolder getSurfaceHolder() {
return mSurfaceHolder;
}
@Nullable
@Override
public SurfaceTexture getSurfaceTexture() {
return null;
}
@Nullable
@Override
public Surface openSurface() {
if (mSurfaceHolder == null) return null;
return mSurfaceHolder.getSurface();
}
}
@Override
public void addRenderCallback(@NonNull IRenderCallback callback) {
mSurfaceCallback.addRenderCallback(callback);
}
@Override
public void removeRenderCallback(@NonNull IRenderCallback callback) {
mSurfaceCallback.removeRenderCallback(callback);
}
private SurfaceCallback mSurfaceCallback;
private static final class SurfaceCallback implements SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private boolean mIsFormatChanged;
private int mFormat;
private int mWidth;
private int mHeight;
private final WeakReference<SurfaceRenderView> mWeakSurfaceView;
private final Map<IRenderCallback, Object> mRenderCallbackMap = new ConcurrentHashMap<>();
private SurfaceCallback(@NonNull SurfaceRenderView surfaceView) {
mWeakSurfaceView = new WeakReference<>(surfaceView);
}
private void addRenderCallback(@NonNull IRenderCallback callback) {
mRenderCallbackMap.put(callback, callback);
ISurfaceHolder surfaceHolder = null;
if (mSurfaceHolder != null) {
surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
callback.onSurfaceCreated(surfaceHolder, mWidth, mHeight);
}
if (mIsFormatChanged) {
if (surfaceHolder == null) surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
callback.onSurfaceChanged(surfaceHolder, mFormat, mWidth, mHeight);
}
}
private void removeRenderCallback(@NonNull IRenderCallback callback) {
mRenderCallbackMap.remove(callback);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
mIsFormatChanged = false;
mFormat = 0;
mWidth = 0;
mHeight = 0;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
renderCallback.onSurfaceCreated(surfaceHolder, 0, 0);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceHolder = null;
mIsFormatChanged = false;
mFormat = 0;
mWidth = 0;
mHeight = 0;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
renderCallback.onSurfaceDestroyed(surfaceHolder);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceHolder = holder;
mIsFormatChanged = true;
mFormat = format;
mWidth = width;
mHeight = height;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
renderCallback.onSurfaceChanged(surfaceHolder, format, width, height);
}
}
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(SurfaceRenderView.class.getName());
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(SurfaceRenderView.class.getName());
}
}

@ -0,0 +1,292 @@
package com.lodz.android.mmsplayer.ijk.media;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.TextureView;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.ISurfaceTextureHolder;
import tv.danmaku.ijk.media.player.ISurfaceTextureHost;
public class TextureRenderView extends TextureView implements IRenderView {
private MeasureHelper mMeasureHelper;
public TextureRenderView(Context context) {
super(context);
initView(context);
}
public TextureRenderView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public TextureRenderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public TextureRenderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initView(context);
}
private void initView(Context context) {
mMeasureHelper = new MeasureHelper(this);
mSurfaceCallback = new SurfaceCallback(this);
setSurfaceTextureListener(mSurfaceCallback);
}
@Override
public View getView() {
return this;
}
@Override
public boolean shouldWaitForResize() {
return false;
}
@Override
protected void onDetachedFromWindow() {
mSurfaceCallback.willDetachFromWindow();
super.onDetachedFromWindow();
mSurfaceCallback.didDetachFromWindow();
}
@Override
public void setVideoSize(int videoWidth, int videoHeight) {
if (videoWidth > 0 && videoHeight > 0) {
mMeasureHelper.setVideoSize(videoWidth, videoHeight);
requestLayout();
}
}
@Override
public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
if (videoSarNum > 0 && videoSarDen > 0) {
mMeasureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen);
requestLayout();
}
}
@Override
public void setVideoRotation(int degree) {
mMeasureHelper.setVideoRotation(degree);
setRotation(degree);
}
@Override
public void setAspectRatio(int aspectRatio) {
mMeasureHelper.setAspectRatio(aspectRatio);
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMeasureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(mMeasureHelper.getMeasuredWidth(), mMeasureHelper.getMeasuredHeight());
}
public IRenderView.ISurfaceHolder getSurfaceHolder() {
return new InternalSurfaceHolder(this, mSurfaceCallback.mSurfaceTexture);
}
private static final class InternalSurfaceHolder implements IRenderView.ISurfaceHolder {
private final TextureRenderView mTextureView;
private final SurfaceTexture mSurfaceTexture;
private InternalSurfaceHolder(@NonNull TextureRenderView textureView, @Nullable SurfaceTexture surfaceTexture) {
mTextureView = textureView;
mSurfaceTexture = surfaceTexture;
}
public void bindToMediaPlayer(IMediaPlayer mp) {
if (mp == null) return;
if (mp instanceof ISurfaceTextureHolder) {
ISurfaceTextureHolder textureHolder = (ISurfaceTextureHolder) mp;
mTextureView.mSurfaceCallback.setOwnSurfaceTexture(false);
SurfaceTexture surfaceTexture = textureHolder.getSurfaceTexture();
if (surfaceTexture != null) {
mTextureView.setSurfaceTexture(surfaceTexture);
} else {
textureHolder.setSurfaceTexture(mSurfaceTexture);
textureHolder.setSurfaceTextureHost(mTextureView.mSurfaceCallback);
}
} else {
mp.setSurface(openSurface());
}
}
@NonNull
@Override
public IRenderView getRenderView() {
return mTextureView;
}
@Nullable
@Override
public SurfaceHolder getSurfaceHolder() {
return null;
}
@Nullable
@Override
public SurfaceTexture getSurfaceTexture() {
return mSurfaceTexture;
}
@Nullable
@Override
public Surface openSurface() {
if (mSurfaceTexture == null) return null;
return new Surface(mSurfaceTexture);
}
}
@Override
public void addRenderCallback(@NonNull IRenderCallback callback) {
mSurfaceCallback.addRenderCallback(callback);
}
@Override
public void removeRenderCallback(@NonNull IRenderCallback callback) {
mSurfaceCallback.removeRenderCallback(callback);
}
private SurfaceCallback mSurfaceCallback;
private static final class SurfaceCallback implements SurfaceTextureListener, ISurfaceTextureHost {
private SurfaceTexture mSurfaceTexture;
private boolean mIsFormatChanged;
private int mWidth;
private int mHeight;
private boolean mOwnSurfaceTexture = true;
private boolean mWillDetachFromWindow = false;
private boolean mDidDetachFromWindow = false;
private final WeakReference<TextureRenderView> mWeakRenderView;
private final Map<IRenderCallback, Object> mRenderCallbackMap = new ConcurrentHashMap<>();
private SurfaceCallback(@NonNull TextureRenderView renderView) {
mWeakRenderView = new WeakReference<>(renderView);
}
private void setOwnSurfaceTexture(boolean ownSurfaceTexture) {
mOwnSurfaceTexture = ownSurfaceTexture;
}
private void addRenderCallback(@NonNull IRenderCallback callback) {
mRenderCallbackMap.put(callback, callback);
ISurfaceHolder surfaceHolder = null;
if (mSurfaceTexture != null) {
surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), mSurfaceTexture);
callback.onSurfaceCreated(surfaceHolder, mWidth, mHeight);
}
if (mIsFormatChanged) {
if (surfaceHolder == null) surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), mSurfaceTexture);
callback.onSurfaceChanged(surfaceHolder, 0, mWidth, mHeight);
}
}
private void removeRenderCallback(@NonNull IRenderCallback callback) {
mRenderCallbackMap.remove(callback);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurfaceTexture = surface;
mIsFormatChanged = false;
mWidth = 0;
mHeight = 0;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) renderCallback.onSurfaceCreated(surfaceHolder, 0, 0);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
mSurfaceTexture = surface;
mIsFormatChanged = true;
mWidth = width;
mHeight = height;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) renderCallback.onSurfaceChanged(surfaceHolder, 0, width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mSurfaceTexture = surface;
mIsFormatChanged = false;
mWidth = 0;
mHeight = 0;
ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakRenderView.get(), surface);
for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) renderCallback.onSurfaceDestroyed(surfaceHolder);
return mOwnSurfaceTexture;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
@Override
public void releaseSurfaceTexture(SurfaceTexture surfaceTexture) {
if (surfaceTexture == null) return;
if (mDidDetachFromWindow) {
if (surfaceTexture != mSurfaceTexture) {
surfaceTexture.release();
} else if (!mOwnSurfaceTexture) {
surfaceTexture.release();
}
} else if (mWillDetachFromWindow) {
if (surfaceTexture != mSurfaceTexture) {
surfaceTexture.release();
} else if (!mOwnSurfaceTexture) {
setOwnSurfaceTexture(true);
}
} else {
if (surfaceTexture != mSurfaceTexture) {
surfaceTexture.release();
} else if (!mOwnSurfaceTexture) {
setOwnSurfaceTexture(true);
}
}
}
private void willDetachFromWindow() {
mWillDetachFromWindow = true;
}
private void didDetachFromWindow() {
mDidDetachFromWindow = true;
}
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(TextureRenderView.class.getName());
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(TextureRenderView.class.getName());
}
}

@ -0,0 +1,128 @@
package com.lodz.android.mmsplayer.ijk.setting;
import androidx.annotation.IntDef;
import com.lodz.android.mmsplayer.ijk.media.IRenderView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class IjkPlayerSetting {
public static IjkPlayerSetting getDefault(){
IjkPlayerSetting setting = new IjkPlayerSetting();
setting.playerType = PlayerType.PLAY_IJK;
setting.isBackgroundPlay = false;
setting.isUsingMediaCodec = true;
setting.isUsingMediaCodecAutoRotate = true;
setting.isMediaCodecHandleResolutionChange = true;
setting.isUsingOpenSLES = true;
setting.pixelFormatType = PixelFormatType.PIXEL_AUTO;
setting.isUsingMediaDataSource = true;
setting.renderViewType = RenderViewType.TEXTURE_VIEW;
setting.isEnableDetachedSurfaceTexture = true;
setting.aspectRatioType = IRenderView.AR_ASPECT_FIT_PARENT;
return setting;
}
//--------------------------- 播放器设置 -----------------------------------
@Retention(RetentionPolicy.SOURCE)
@IntDef({PlayerType.PALY_ANDROID_MEDIA, PlayerType.PLAY_IJK})
public @interface PlayerType {
/** android原生播放器 */
int PALY_ANDROID_MEDIA = 1;
/** Ijk播放器 */
int PLAY_IJK = 2;
}
/** 播放器类型 */
@PlayerType
public int playerType = PlayerType.PLAY_IJK;
//--------------------------- 后台播放设置 -----------------------------------
/** 是否后台播放(4.0+) */
public boolean isBackgroundPlay = false;
//--------------------------- 硬解码设置 -----------------------------------
/** 是否使用硬解码 */
public boolean isUsingMediaCodec = true;
/** 是否使用硬解码下自动旋转 */
public boolean isUsingMediaCodecAutoRotate = true;
/** 是否使用硬解码下处理分辨率更改 */
public boolean isMediaCodecHandleResolutionChange = true;
//--------------------------- 使用OpenGLES -----------------------------------
/** 是否使用OpenGLES */
public boolean isUsingOpenSLES = true;
//--------------------------- 设置像素格式 -----------------------------------
@Retention(RetentionPolicy.SOURCE)
@IntDef({PixelFormatType.PIXEL_AUTO, PixelFormatType.PIXEL_RGB_565, PixelFormatType.PIXEL_RGB_888, PixelFormatType.PIXEL_RGBX_8888,
PixelFormatType.PIXEL_YV12, PixelFormatType.PIXEL_OPENGL_ES2})
public @interface PixelFormatType {
/** 自动选择 */
int PIXEL_AUTO = 0;
/** RGB 565 */
int PIXEL_RGB_565 = 1;
/** RGB 888 */
int PIXEL_RGB_888 = 2;
/** RGBX 8888 */
int PIXEL_RGBX_8888 = 3;
/** YV12 */
int PIXEL_YV12 = 4;
/** OpenGL ES2 */
int PIXEL_OPENGL_ES2 = 5;
}
/** 像素格式 */
@PixelFormatType
public int pixelFormatType = PixelFormatType.PIXEL_AUTO;
//--------------------------- 使用数据源 -----------------------------------
/** 是否使用数据源(需要6.0+且播放本地文件) */
public boolean isUsingMediaDataSource = true;
//--------------------------- 渲染的view -----------------------------------
@Retention(RetentionPolicy.SOURCE)
@IntDef({RenderViewType.NO_VIEW, RenderViewType.SURFACE_VIEW, RenderViewType.TEXTURE_VIEW})
public @interface RenderViewType {
/** 不使用渲染的view */
int NO_VIEW = 0;
/** 用surfaceview渲染 */
int SURFACE_VIEW = 1;
/** 用textureview渲染 */
int TEXTURE_VIEW = 2;
}
/** 渲染的view的类型 */
@RenderViewType
public int renderViewType = RenderViewType.TEXTURE_VIEW;
/** 是否使用SurfaceTexture处理视频图像 */
public boolean isEnableDetachedSurfaceTexture = true;
//--------------------------- 播放器长宽比类型 -----------------------------------
@Retention(RetentionPolicy.SOURCE)
@IntDef({IRenderView.AR_ASPECT_FIT_PARENT, IRenderView.AR_ASPECT_FILL_PARENT, IRenderView.AR_ASPECT_WRAP_CONTENT,
IRenderView.AR_16_9_FIT_PARENT, IRenderView.AR_4_3_FIT_PARENT})
public @interface AspectRatioType {}
@AspectRatioType
public int aspectRatioType = IRenderView.AR_ASPECT_FIT_PARENT;
@Override
public String toString() {
return "IjkPlayerSetting{" +
"\n playerType=" + playerType +
", \n isBackgroundPlay=" + isBackgroundPlay +
", \n isUsingMediaCodec=" + isUsingMediaCodec +
", \n isUsingMediaCodecAutoRotate=" + isUsingMediaCodecAutoRotate +
", \n isMediaCodecHandleResolutionChange=" + isMediaCodecHandleResolutionChange +
", \n isUsingOpenSLES=" + isUsingOpenSLES +
", \n pixelFormatType=" + pixelFormatType +
", \n isUsingMediaDataSource=" + isUsingMediaDataSource +
", \n renderViewType=" + renderViewType +
", \n isEnableDetachedSurfaceTexture=" + isEnableDetachedSurfaceTexture +
", \n aspectRatioType=" + aspectRatioType +
'}';
}
}

@ -0,0 +1,71 @@
package com.lodz.android.mmsplayer.ijk.utils;
import android.content.Context;
import android.text.TextUtils;
import com.lodz.android.mmsplayer.R;
import java.util.Locale;
import tv.danmaku.ijk.media.player.misc.ITrackInfo;
/**
* 视频信息帮助类
* Created by zhouL on 2016/12/1.
*/
public class MediaInfoUtils {
public static String buildResolution(int width, int height, int sarNum, int sarDen) {
StringBuilder sb = new StringBuilder();
sb.append(width);
sb.append(" x ");
sb.append(height);
if (sarNum > 1 || sarDen > 1) {
sb.append("[");
sb.append(sarNum);
sb.append(":");
sb.append(sarDen);
sb.append("]");
}
return sb.toString();
}
public static String buildTimeMilli(long duration) {
long total_seconds = duration / 1000;
long hours = total_seconds / 3600;
long minutes = (total_seconds % 3600) / 60;
long seconds = total_seconds % 60;
if (duration <= 0) {
return "00:00";
}
if (hours >= 100) {
return String.format(Locale.US, "%d:%02d:%02d", hours, minutes, seconds);
} else if (hours > 0) {
return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes, seconds);
} else {
return String.format(Locale.US, "%02d:%02d", minutes, seconds);
}
}
public static String buildTrackType(Context context, int type) {
switch (type) {
case ITrackInfo.MEDIA_TRACK_TYPE_VIDEO:
return context.getString(R.string.mmsplayer_tracktype_video);
case ITrackInfo.MEDIA_TRACK_TYPE_AUDIO:
return context.getString(R.string.mmsplayer_tracktype_audio);
case ITrackInfo.MEDIA_TRACK_TYPE_SUBTITLE:
return context.getString(R.string.mmsplayer_tracktype_subtitle);
case ITrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT:
return context.getString(R.string.mmsplayer_tracktype_timedtext);
case ITrackInfo.MEDIA_TRACK_TYPE_METADATA:
return context.getString(R.string.mmsplayer_tracktype_metadata);
case ITrackInfo.MEDIA_TRACK_TYPE_UNKNOWN:
default:
return context.getString(R.string.mmsplayer_tracktype_unknown);
}
}
public static String buildLanguage(String language) {
return TextUtils.isEmpty(language)? "N/A" : language;
}
}

@ -188,7 +188,6 @@ public final class IjkMediaPlayer extends AbstractMediaPlayer {
libLoader = sLocalLibLoader;
libLoader.loadLibrary("ijkffmpeg");
libLoader.loadLibrary("ijksdl");
libLoader.loadLibrary("ijkplayer");
mIsLibLoaded = true;
}

Loading…
Cancel
Save