ijkplayer是Bilibili基于ffmpeg開(kāi)發(fā)并開(kāi)源的輕量級(jí)視頻播放器,支持播放本地網(wǎng)絡(luò)視頻,也支持流媒體播放。支持Android&iOS。
南海網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)2013年開(kāi)創(chuàng)至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
ijkplayer的編譯這里不多闡述,我也是直接獲取別人編譯完成的so庫(kù)文件,直接使用的。如果你對(duì)ijkplayer的編譯感興趣,可以百度一下,有很多文章。
使用ijkplayer
導(dǎo)包
ijkplayer源碼官方下載地址:https://github.com/Bilibili/ijkplayer
上面是官方提供的ijkplayer的源碼地址,但是它是沒(méi)有編譯過(guò)的。下面我給大家分享一份編譯好的ijkplayer源碼,由于比較大,分了三個(gè)包才上傳完成,需要三個(gè)包都下載后才能一起解壓: ijkplayer_jb51.rar
我們下載完成,進(jìn)入android/ijkplayer目錄:
官方提供的Demo的代碼還是挺多的,甚至還用了otto,需要對(duì)官方的demo進(jìn)行精簡(jiǎn),去除一些用不到的代碼。
首先需要的是ijkplayer-{arch}、ijkplayer-java兩個(gè)庫(kù)。exo是Google提供的新的播放器,這里不需要,直接砍掉。其次是ijkplayer-example里的,我們需要的只有tv.danmaku.ijk.media.example.widget.media包下的部分類。
注:
鏈接庫(kù)ijkplayer-arm64,ijkplayer-armv5,ijkplayer-armv7a,ijkplayer-x86,ijkplayer-x86_64是不同體系架構(gòu)的動(dòng)態(tài)鏈接庫(kù),在當(dāng)前工程結(jié)構(gòu)里面作為一個(gè)模塊,如果不想做兼容多平臺(tái)問(wèn)題,可以刪除其他目錄結(jié)構(gòu),單獨(dú)保留自己需要的平臺(tái)目錄。
新建一個(gè)工程:
(1)把ijkplayer-armv7a/src/main/libs下的文件拷貝到新工程app目錄的libs下。
(2)把ijkplayer-java/build/outputs/aar/ijkplayer-java-release.aar復(fù)制到新工程app目錄的libs下。
(3)修改APP下的build.gradle, 主要設(shè)置.so及.aar的位置:
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "25.0.0" defaultConfig { applicationId "com.hx.ijkplayer_demo" minSdkVersion 14 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { jniLibs.srcDirs = ['libs'] /**在libs文件夾下找so文件*/ } } } repositories { mavenCentral() flatDir { dirs 'libs' /**在libs文件夾下找aar文件*/ } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' compile(name: 'ijkplayer-java-release', ext: 'aar') /**編譯ijkplayer-java-release.aar文件*/ }
(4)復(fù)制ijkplayer-example下面的tv.danmaku.ijk.media.example.widget.media到新的工程,刪掉一些不需要類。
(5)IjkVideoView里面還是有很多如exo等沒(méi)用的東西,刪!具體可以參見(jiàn)我后面的Demo。
(6)Manifest
... <activity android:name=".MainActivity" android:screenOrientation="sensorLandscape" android:configChanges="orientation|keyboardHidden"> ... </activity> ... <uses-permission android:name="android.permission.INTERNET"/>
播放實(shí)現(xiàn)
Xml代碼
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.hx.ijkplayer_demo.widget.media.IjkVideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
Java代碼
public class MainActivity extends AppCompatActivity { private IjkVideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); videoView = (IjkVideoView) findViewById(R.id.video_view); videoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT); videoView.setVideoURI(Uri.parse("http://zv.3gv.ifeng.com/live/zhongwen800k.m3u8")); videoView.start(); } }
常用函數(shù)
/** * 參數(shù)aspectRatio(縮放參數(shù))參見(jiàn)IRenderView的常量:IRenderView.AR_ASPECT_FIT_PARENT, IRenderView.AR_ASPECT_FILL_PARENT, IRenderView.AR_ASPECT_WRAP_CONTENT, IRenderView.AR_MATCH_PARENT, IRenderView.AR_16_9_FIT_PARENT, IRenderView.AR_4_3_FIT_PARENT */ public void setAspectRatio(int aspectRatio); //改變視頻縮放狀態(tài)。 public int toggleAspectRatio(); //設(shè)置視頻路徑。 public void setVideoPath(String path); //設(shè)置視頻URI。(可以是網(wǎng)絡(luò)視頻地址) public void setVideoURI(Uri uri); //停止視頻播放,并釋放資源。 public void stopPlayback(); /** * 設(shè)置媒體控制器。 * 參數(shù)controller:媒體控制器,注意是com.hx.ijkplayer_demo.widget.media.IMediaController。 */ public void setMediaController(IMediaController controller); //改變媒體控制器顯隱 private void toggleMediaControlsVisiblity(); //注冊(cè)一個(gè)回調(diào)函數(shù),在視頻預(yù)處理完成后調(diào)用。在視頻預(yù)處理完成后被調(diào)用。此時(shí)視頻的寬度、高度、寬高比信息已經(jīng)獲取到,此時(shí)可調(diào)用seekTo讓視頻從指定位置開(kāi)始播放。 public void setOnPreparedListener(OnPreparedListener l); //播放完成回調(diào) public void setOnCompletionListener(IMediaPlayer.OnCompletionListener l); //播放錯(cuò)誤回調(diào) public void setOnErrorListener(IMediaPlayer.OnErrorListener l); //事件發(fā)生回調(diào) public void setOnInfoListener(IMediaPlayer.OnInfoListener l); //獲取總長(zhǎng)度 public int getDuration(); //獲取當(dāng)前播放位置。 public long getCurrentPosition(); //設(shè)置播放位置。單位毫秒 public void seekTo(long msec); //是否正在播放。 public boolean isPlaying(); //獲取緩沖百分比。 public int getBufferPercentage();
封裝ijkplayer
上面只是ijkplayer的一個(gè)基本用法。我們可以對(duì)ijkplayer進(jìn)行一次封裝,讓ijkplayer使用起來(lái)更加簡(jiǎn)單。
功能:
public class PlayerManager { /** * 可能會(huì)剪裁,保持原視頻的大小,顯示在中心,當(dāng)原視頻的大小超過(guò)view的大小超過(guò)部分裁剪處理 */ public static final String SCALETYPE_FITPARENT="fitParent"; /** * 可能會(huì)剪裁,等比例放大視頻,直到填滿View為止,超過(guò)View的部分作裁剪處理 */ public static final String SCALETYPE_FILLPARENT="fillParent"; /** * 將視頻的內(nèi)容完整居中顯示,如果視頻大于view,則按比例縮視頻直到完全顯示在view中 */ public static final String SCALETYPE_WRAPCONTENT="wrapContent"; /** * 不剪裁,非等比例拉伸畫面填滿整個(gè)View */ public static final String SCALETYPE_FITXY="fitXY"; /** * 不剪裁,非等比例拉伸畫面到16:9,并完全顯示在View中 */ public static final String SCALETYPE_16_9="16:9"; /** * 不剪裁,非等比例拉伸畫面到4:3,并完全顯示在View中 */ public static final String SCALETYPE_4_3="4:3"; /** * 狀態(tài)常量 */ private final int STATUS_ERROR=-1; private final int STATUS_IDLE=0; private final int STATUS_LOADING=1; private final int STATUS_PLAYING=2; private final int STATUS_PAUSE=3; private final int STATUS_COMPLETED=4; private final Activity activity; private final IjkVideoView videoView; private final AudioManager audioManager; public GestureDetector gestureDetector; private boolean playerSupport; private boolean isLive = false;//是否為直播 private boolean fullScreenOnly; private boolean portrait; private final int mMaxVolume; private int screenWidthPixels; private int currentPosition; private int status=STATUS_IDLE; private long pauseTime; private String url; private float brightness=-1; private int volume=-1; private long newPosition = -1; private long defaultRetryTime=5000; private OrientationEventListener orientationEventListener; private PlayerStateListener playerStateListener; public void setPlayerStateListener(PlayerStateListener playerStateListener) { this.playerStateListener = playerStateListener; } private OnErrorListener onErrorListener=new OnErrorListener() { @Override public void onError(int what, int extra) { } }; private OnCompleteListener onCompleteListener=new OnCompleteListener() { @Override public void onComplete() { } }; private OnInfoListener onInfoListener=new OnInfoListener(){ @Override public void onInfo(int what, int extra) { } }; private OnControlPanelVisibilityChangeListener onControlPanelVisibilityChangeListener=new OnControlPanelVisibilityChangeListener() { @Override public void change(boolean isShowing) { } }; /** * try to play when error(only for live video) * @param defaultRetryTime millisecond,0 will stop retry,default is 5000 millisecond */ public void setDefaultRetryTime(long defaultRetryTime) { this.defaultRetryTime = defaultRetryTime; } public PlayerManager(final Activity activity) { try { IjkMediaPlayer.loadLibrariesOnce(null); IjkMediaPlayer.native_profileBegin("libijkplayer.so"); playerSupport=true; } catch (Throwable e) { Log.e("GiraffePlayer", "loadLibraries error", e); } this.activity=activity; screenWidthPixels = activity.getResources().getDisplayMetrics().widthPixels; videoView = (IjkVideoView) activity.findViewById(R.id.video_view); videoView.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() { @Override public void onCompletion(IMediaPlayer mp) { statusChange(STATUS_COMPLETED); onCompleteListener.onComplete(); } }); videoView.setOnErrorListener(new IMediaPlayer.OnErrorListener() { @Override public boolean onError(IMediaPlayer mp, int what, int extra) { statusChange(STATUS_ERROR); onErrorListener.onError(what,extra); return true; } }); videoView.setOnInfoListener(new IMediaPlayer.OnInfoListener() { @Override public boolean onInfo(IMediaPlayer mp, int what, int extra) { switch (what) { case IMediaPlayer.MEDIA_INFO_BUFFERING_START: statusChange(STATUS_LOADING); break; case IMediaPlayer.MEDIA_INFO_BUFFERING_END: statusChange(STATUS_PLAYING); break; case IMediaPlayer.MEDIA_INFO_NETWORK_BANDWIDTH: //顯示下載速度 // Toast.show("download rate:" + extra); break; case IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: statusChange(STATUS_PLAYING); break; } onInfoListener.onInfo(what,extra); return false; } }); audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); mMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); gestureDetector = new GestureDetector(activity, new PlayerGestureListener()); if (fullScreenOnly) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } portrait=getScreenOrientation()== ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; if (!playerSupport) { DebugLog.e("播放器不支持此設(shè)備"); } } private void statusChange(int newStatus) { status = newStatus; if (!isLive && newStatus==STATUS_COMPLETED) { DebugLog.d("statusChange STATUS_COMPLETED..."); if (playerStateListener != null){ playerStateListener.onComplete(); } }else if (newStatus == STATUS_ERROR) { DebugLog.d("statusChange STATUS_ERROR..."); if (playerStateListener != null){ playerStateListener.onError(); } } else if(newStatus==STATUS_LOADING){ // $.id(R.id.app_video_loading).visible(); if (playerStateListener != null){ playerStateListener.onLoading(); } DebugLog.d("statusChange STATUS_LOADING..."); } else if (newStatus == STATUS_PLAYING) { DebugLog.d("statusChange STATUS_PLAYING..."); if (playerStateListener != null){ playerStateListener.onPlay(); } } } public void onPause() { pauseTime= System.currentTimeMillis(); if (status==STATUS_PLAYING) { videoView.pause(); if (!isLive) { currentPosition = videoView.getCurrentPosition(); } } } public void onResume() { pauseTime=0; if (status==STATUS_PLAYING) { if (isLive) { videoView.seekTo(0); } else { if (currentPosition>0) { videoView.seekTo(currentPosition); } } videoView.start(); } } public void onDestroy() { orientationEventListener.disable(); videoView.stopPlayback(); } public void play(String url) { this.url = url; if (playerSupport) { videoView.setVideoPath(url); videoView.start(); } } private String generateTime(long time) { int totalSeconds = (int) (time / 1000); int seconds = totalSeconds % 60; int minutes = (totalSeconds / 60) % 60; int hours = totalSeconds / 3600; return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds); } private int getScreenOrientation() { int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); DisplayMetrics dm = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; int orientation; // if the device's natural orientation is portrait: if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && height > width || (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && width > height) { switch (rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; default: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; } } // if the device's natural orientation is landscape or if the device // is square: else { switch (rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; default: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; } } return orientation; } /** * 滑動(dòng)改變聲音大小 * * @param percent */ private void onVolumeSlide(float percent) { if (volume == -1) { volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); if (volume < 0) volume = 0; } int index = (int) (percent * mMaxVolume) + volume; if (index > mMaxVolume) { index = mMaxVolume; } else if (index < 0){ index = 0; } // 變更聲音 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0); // 變更進(jìn)度條 int i = (int) (index * 1.0 / mMaxVolume * 100); String s = i + "%"; if (i == 0) { s = "off"; } DebugLog.d("onVolumeSlide:"+s); } private void onProgressSlide(float percent) { long position = videoView.getCurrentPosition(); long duration = videoView.getDuration(); long deltaMax = Math.min(100 * 1000, duration - position); long delta = (long) (deltaMax * percent); newPosition = delta + position; if (newPosition > duration) { newPosition = duration; } else if (newPosition <= 0) { newPosition=0; delta=-position; } int showDelta = (int) delta / 1000; if (showDelta != 0) { String text = showDelta > 0 ? ("+" + showDelta) : "" + showDelta; DebugLog.d("onProgressSlide:" + text); } } /** * 滑動(dòng)改變亮度 * * @param percent */ private void onBrightnessSlide(float percent) { if (brightness < 0) { brightness = activity.getWindow().getAttributes().screenBrightness; if (brightness <= 0.00f){ brightness = 0.50f; }else if (brightness < 0.01f){ brightness = 0.01f; } } DebugLog.d("brightness:"+brightness+",percent:"+ percent); WindowManager.LayoutParams lpa = activity.getWindow().getAttributes(); lpa.screenBrightness = brightness + percent; if (lpa.screenBrightness > 1.0f){ lpa.screenBrightness = 1.0f; }else if (lpa.screenBrightness < 0.01f){ lpa.screenBrightness = 0.01f; } activity.getWindow().setAttributes(lpa); } public void setFullScreenOnly(boolean fullScreenOnly) { this.fullScreenOnly = fullScreenOnly; tryFullScreen(fullScreenOnly); if (fullScreenOnly) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); } } private void tryFullScreen(boolean fullScreen) { if (activity instanceof AppCompatActivity) { ActionBar supportActionBar = ((AppCompatActivity) activity).getSupportActionBar(); if (supportActionBar != null) { if (fullScreen) { supportActionBar.hide(); } else { supportActionBar.show(); } } } setFullScreen(fullScreen); } private void setFullScreen(boolean fullScreen) { if (activity != null) { WindowManager.LayoutParams attrs = activity.getWindow().getAttributes(); if (fullScreen) { attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; activity.getWindow().setAttributes(attrs); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } else { attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN); activity.getWindow().setAttributes(attrs); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } } } /** * <pre> * fitParent:可能會(huì)剪裁,保持原視頻的大小,顯示在中心,當(dāng)原視頻的大小超過(guò)view的大小超過(guò)部分裁剪處理 * fillParent:可能會(huì)剪裁,等比例放大視頻,直到填滿View為止,超過(guò)View的部分作裁剪處理 * wrapContent:將視頻的內(nèi)容完整居中顯示,如果視頻大于view,則按比例縮視頻直到完全顯示在view中 * fitXY:不剪裁,非等比例拉伸畫面填滿整個(gè)View * 16:9:不剪裁,非等比例拉伸畫面到16:9,并完全顯示在View中 * 4:3:不剪裁,非等比例拉伸畫面到4:3,并完全顯示在View中 * </pre> * @param scaleType */ public void setScaleType(String scaleType) { if (SCALETYPE_FITPARENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT); }else if (SCALETYPE_FILLPARENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_FILL_PARENT); }else if (SCALETYPE_WRAPCONTENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_WRAP_CONTENT); }else if (SCALETYPE_FITXY.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_MATCH_PARENT); }else if (SCALETYPE_16_9.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_16_9_FIT_PARENT); }else if (SCALETYPE_4_3.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_4_3_FIT_PARENT); } } public void start() { videoView.start(); } public void pause() { videoView.pause(); } public boolean onBackPressed() { if (!fullScreenOnly && getScreenOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); return true; } return false; } class Query { private final Activity activity; private View view; public Query(Activity activity) { this.activity=activity; } public Query id(int id) { view = activity.findViewById(id); return this; } public Query image(int resId) { if (view instanceof ImageView) { ((ImageView) view).setImageResource(resId); } return this; } public Query visible() { if (view != null) { view.setVisibility(View.VISIBLE); } return this; } public Query gone() { if (view != null) { view.setVisibility(View.GONE); } return this; } public Query invisible() { if (view != null) { view.setVisibility(View.INVISIBLE); } return this; } public Query clicked(View.OnClickListener handler) { if (view != null) { view.setOnClickListener(handler); } return this; } public Query text(CharSequence text) { if (view!=null && view instanceof TextView) { ((TextView) view).setText(text); } return this; } public Query visibility(int visible) { if (view != null) { view.setVisibility(visible); } return this; } private void size(boolean width, int n, boolean dip){ if(view != null){ ViewGroup.LayoutParams lp = view.getLayoutParams(); if(n > 0 && dip){ n = dip2pixel(activity, n); } if(width){ lp.width = n; }else{ lp.height = n; } view.setLayoutParams(lp); } } public void height(int height, boolean dip) { size(false,height,dip); } public int dip2pixel(Context context, float n){ int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, n, context.getResources().getDisplayMetrics()); return value; } public float pixel2dip(Context context, float n){ Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float dp = n / (metrics.densityDpi / 160f); return dp; } } public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListener { private boolean firstTouch; private boolean volumeControl; private boolean toSeek; /** * 雙擊 */ @Override public boolean onDoubleTap(MotionEvent e) { videoView.toggleAspectRatio(); return true; } @Override public boolean onDown(MotionEvent e) { firstTouch = true; return super.onDown(e); } /** * 滑動(dòng) */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { float mOldX = e1.getX(), mOldY = e1.getY(); float deltaY = mOldY - e2.getY(); float deltaX = mOldX - e2.getX(); if (firstTouch) { toSeek = Math.abs(distanceX) >= Math.abs(distanceY); volumeControl=mOldX > screenWidthPixels * 0.5f; firstTouch = false; } if (toSeek) { if (!isLive) { onProgressSlide(-deltaX / videoView.getWidth()); } } else { float percent = deltaY / videoView.getHeight(); if (volumeControl) { onVolumeSlide(percent); } else { onBrightnessSlide(percent); } } return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onSingleTapUp(MotionEvent e) { return true; } } /** * is player support this device * @return */ public boolean isPlayerSupport() { return playerSupport; } /** * 是否正在播放 * @return */ public boolean isPlaying() { return videoView!=null?videoView.isPlaying():false; } public void stop(){ videoView.stopPlayback(); } public int getCurrentPosition(){ return videoView.getCurrentPosition(); } /** * get video duration * @return */ public int getDuration(){ return videoView.getDuration(); } public PlayerManager playInFullScreen(boolean fullScreen){ if (fullScreen) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } return this; } public PlayerManager onError(OnErrorListener onErrorListener) { this.onErrorListener = onErrorListener; return this; } public PlayerManager onComplete(OnCompleteListener onCompleteListener) { this.onCompleteListener = onCompleteListener; return this; } public PlayerManager onInfo(OnInfoListener onInfoListener) { this.onInfoListener = onInfoListener; return this; } public PlayerManager onControlPanelVisibilityChange(OnControlPanelVisibilityChangeListener listener){ this.onControlPanelVisibilityChangeListener = listener; return this; } /** * set is live (can't seek forward) * @param isLive * @return */ public PlayerManager live(boolean isLive) { this.isLive = isLive; return this; } public PlayerManager toggleAspectRatio(){ if (videoView != null) { videoView.toggleAspectRatio(); } return this; } public interface PlayerStateListener{ void onComplete(); void onError(); void onLoading(); void onPlay(); } public interface OnErrorListener{ void onError(int what, int extra); } public interface OnCompleteListener{ void onComplete(); } public interface OnControlPanelVisibilityChangeListener{ void change(boolean isShowing); } public interface OnInfoListener{ void onInfo(int what, int extra); } }
使用封裝后的PlayerManager播放視頻:
public class MainActivity extends AppCompatActivity implements PlayerManager.PlayerStateListener{ private String url1 = "rtmp://203.207.99.19:1935/live/CCTV5"; private String url2 = "http://zv.3gv.ifeng.com/live/zhongwen800k.m3u8"; private String url3 = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov"; private String url4 = "http://42.96.249.166/live/24035.m3u8"; private PlayerManager player; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initPlayer(); } private void initPlayer() { player = new PlayerManager(this); player.setFullScreenOnly(true); player.setScaleType(PlayerManager.SCALETYPE_FILLPARENT); player.playInFullScreen(true); player.setPlayerStateListener(this); player.play(url1); } @Override public boolean onTouchEvent(MotionEvent event) { if (player.gestureDetector.onTouchEvent(event)) return true; return super.onTouchEvent(event); } @Override public void onComplete() { } @Override public void onError() { } @Override public void onLoading() { } @Override public void onPlay() { } }
Demo下載地址
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
新聞名稱:Androidijkplayer的使用方法解析
標(biāo)題URL:http://www.rwnh.cn/article0/jcjgio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、App設(shè)計(jì)、網(wǎng)站維護(hù)、動(dòng)態(tài)網(wǎng)站、網(wǎng)站內(nèi)鏈、軟件開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)