項目開發(fā)使用框架多多少少會遇到各種棘手問題,但是并不是給你一個框架啥的你放進去就能用,一般簡單的操作很容易解決,當設計到自己開發(fā)的東西比較老,復雜;而且你又想用這些新技術,那么你就的對它各種處理使得與你的項目兼容才行 ;但是如果你是大牛的話完全可以忽略這種做法,完全可以自己封裝一個視頻處理框架##
雖然有很多人在用JCVideoPlayer做視頻播放,也有很多人在寫博客,每個人都會遇到相同或者不同的問題需要解決,我遇到的問題我總會想方設法把它記錄下來,不希望自己走過的坑再走第二遍,也希望與我遇見同樣問題的人能夠快速的脫離苦海;其次也是希望自己能多研究這方面的東西,向為中國互聯(lián)網(wǎng)做出貢獻的前輩致敬;雖然自己現(xiàn)在還在連菜鳥都算不上,但是希望自己以后更加努力學習也能寫出一些類似的框架。
首先既然我在這里寫到了我們還是來簡單看看節(jié)操videoplayer的簡單用法:
第一步:
第一種方式:
可以通過添加jar包
這種方式的話如果你不希望在他的基礎上采用二次開發(fā)的最后的選擇方法,用起來比較簡單,自己寫入的時候變可以考慮他的兼容性,在此作者采用了第二種方式
這種方式的是通過導入model的形式進行添加,添加成功以后既可以在源碼的基礎上進行二次開發(fā)
第二步:
在用到layout的xml文件夾下面添加類似videoview這種的控件如下圖,將它替換即可
第三步:
在用到節(jié)操player的控件的地方設置他的uri,縮略圖,標題等,在這里節(jié)操videoplayer給我們提供的是String類型的視頻網(wǎng)址,但是如果遇到URI類型的只需要將struri = uri.toString();struri 就能夠支持加載URI了。
下面這個是原來作者的寫法
第四步:
在用到的播放器activity或者fragment的調(diào)用,在清單文件中設置
下面這是jcplayer原作者的GitHub地址,遇到的一些問題在這還得感謝原作者給我的幫助,喜歡的可以去start一下,不懂的盡量Issues:
https://github.com/lipangit/JieCaoVideoPlayer
以上就是原來的用法,可以參照原作者的就行不需要像我的這么大費周折,下面是我使用后遇到的問題以及解決辦法
這里可以看看我用到的項目中activity的父類是繼承于activity的;然而jcplayer得繼承AppCompatActivity的基礎上才行,如果不繼承在全屏的時候無法隱藏toolbar,所以便會導致一個結果就是點擊全屏出現(xiàn)以下異常:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.zontonec.ztgarden, PID: 27388
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v7.app.ActionBar android.support.v7.app.AppCompatActivity.getSupportActionBar()' on a null object reference
at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.hideSupportActionBar(JCVideoPlayer.java:864)
at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.startWindowFullscreen(JCVideoPlayer.java:638)
at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.onClick(JCVideoPlayer.java:190)
at fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard.onClick(JCVideoPlayerStandard.java:176)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:20976)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
分析后他給我們反映的是需要支持v7包下面.AppCompatActivity調(diào)用getSupportActionBar出現(xiàn)空指針異常,也就是說此時我們用到的項目中不能進行隱藏toolbar,從而出現(xiàn)空指針異常,那么知道問啥了我們也就知道如何下手了,在此我們項目中用到的關于繼承activity的內(nèi)容過多,如果冒然修改為繼承AppCompatActivity的話我們的工作量將會相當?shù)拇?,所有我們的從jcplayer的源碼入手解決問題,讓他來兼容我們的項目。
public static void hideSupportActionBar(Context context) {
// if (ACTION_BAR_EXIST) {
// ActionBar ab = JCUtils.getAppCompActivity(context).getSupportActionBar();
// if (ab != null) {
// ab.setShowHideAnimationEnabled(false);
// ab.hide();
// }
// }
if (TOOL_BAR_EXIST) {
JCUtils.getAppCompActivity(context).getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
public static void showSupportActionBar(Context context) {
// if (ACTION_BAR_EXIST) {
// ActionBar ab = JCUtils.getAppCompActivity(context).getSupportActionBar();
// if (ab != null) {
// ab.setShowHideAnimationEnabled(false);
// ab.show();
// }
// }
if (TOOL_BAR_EXIST) {
JCUtils.getAppCompActivity(context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
在源碼jcvideoplayer下面,我們可以發(fā)現(xiàn)下面條件是,如果點擊全屏時候actionbar存在的話,我們的將它隱藏,然而我們的activity并不支持,解決辦法也就得從這里入手了,我們只需要將用到隱藏actionbar的代碼,注釋或者刪除掉就行,你以為這樣就行了嗎?不行事情還沒解決,運行照樣崩潰,再看下面這段代碼
/**
* Get activity from context object
*
* @param context something
* @return object of Activity or null if it is not Activity
*/
//源碼中這里是AppCompatActivity我們將它改為activity即、可,下面這段代碼就是我修改過后的
public static ***AppCompatActivity*** scanForActivity(Context context) {
if (context == null) return null;
if (context instanceof ***AppCompatActivity***) {
return (***AppCompatActivity***) context;
} else if (context instanceof ContextWrapper) {
return scanForActivity(((ContextWrapper) context).getBaseContext());
}
return null;
}
/**
* Get AppCompatActivity from context
*
* @param context
* @return AppCompatActivity if it's not null
*/
//修改過的,同樣上面那個代碼需要修改了和static后面的activity的一致,源碼地方修改到了這,砸門運行看看,絕對能進入全屏了
public static Activity getAppCompActivity(Context context) {
if (context == null) return null;
if (context instanceof Activity) {
return (Activity) context;
} else if (context instanceof ContextThemeWrapper) {
return getAppCompActivity(((ContextThemeWrapper) context).getBaseContext());
}
return null;
}
但是在此時你又會遇到第三個問題,就是如果你播放的是本地相機錄制的視頻時,他將會會對視頻全屏時的寬高進行設置,同樣視頻播放完畢是又出現(xiàn)下面這個問題了
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.zontonec.ztgarden, PID: 10376
java.lang.NullPointerException: Attempt to invoke virtual method 'void fm.jiecao.jcvideoplayer_lib.JCResizeTextureView.setVideoSize(android.graphics.Point)' on a null object reference
at fm.jiecao.jcvideoplayer_lib.JCVideoPlayer.onVideoSizeChanged(JCVideoPlayer.java:578)
at fm.jiecao.jcvideoplayer_lib.JCMediaManager$7.run(JCMediaManager.java:228)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6145)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
他說我們在setVideoSize時出現(xiàn)了空指針異常,為啥出現(xiàn)這問題呢?按理說在這里根本不會出現(xiàn)這個問題的了,根據(jù)異常的地方JCResizeTextureView這里在我們項目中出現(xiàn)問題了。好的下面就是解決問題的地方了,我們需要將源碼中的兩句代碼 判空部分注釋掉
//JCMediaManager.textureView = null;
//JCMediaManager.savedSurfaceTexture = null;
public void onAutoCompletion() {
//加上這句,避免循環(huán)播放video的時候,內(nèi)存不斷飆升。
Runtime.getRuntime().gc();
Log.i(TAG, "onAutoCompletion " + " [" + this.hashCode() + "] ");
onEvent(JCUserAction.ON_AUTO_COMPLETE);
dismissVolumeDialog();
dismissProgressDialog();
dismissBrightnessDialog();
cancelProgressTimer();
setUiWitStateAndScreen(CURRENT_STATE_AUTO_COMPLETE);
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
backPress();
}
JCUtils.saveProgress(getContext(), url, 0);
/**
* Created by kris-liutao on 2017.
* 此處需要注釋 不然會報setvideosize異常
*/
// JCMediaManager.textureView = null;
// JCMediaManager.savedSurfaceTexture = null;
}
幾經(jīng)波折,在運行試試,好的所有問題全部解決了全屏正常播放。但是在此我更建議采用原作者的用法,這也是沒有辦法的辦法的,如果能在原基礎上解決問題的盡量在原基礎上,找起來問題來也不是很容易的。