⑴ android 如何實現圖片視頻混合播放啊
直接上代碼:
布局文件就是兩個全屏的videoview和imageview重疊
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/pictureView"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
java部分:
/*
視頻圖片混合展示demo
*/
packagecom.example.administrator.hunbo;
importandroid.content.Context;
importandroid.media.MediaPlayer;
importandroid.net.Uri;
importandroid.os.Handler;
importandroid.os.storage.StorageManager;
importandroid.support.v7.app.AppCompatActivity;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.ImageView;
importandroid.widget.Toast;
importandroid.widget.VideoView;
importjava.io.File;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
{
privateVideoViewvideoView;
privateImageViewpictureView;
booleanisPlaying=false;
privateArrayListarrayList=newArrayList<String>();
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();//隱藏actionBar
//初始化控制項
videoView=findViewById(R.id.videoView);
pictureView=findViewById(R.id.pictureView);
//最開始兩個view都是隱藏的
videoView.setVisibility(View.GONE);
pictureView.setVisibility(View.GONE);
//檢測SD卡是否存在
String[]result=null;
StorageManagerstorageManager=(StorageManager)getSystemService(Context.STORAGE_SERVICE);
try{
Methodmethod=StorageManager.class.getMethod("getVolumePaths");
method.setAccessible(true);
try{
result=(String[])method.invoke(storageManager);
}catch(InvocationTargetExceptione){
e.printStackTrace();
}
if(result.length>1){
//Toast.makeText(this,"檢測到U盤",Toast.LENGTH_SHORT).show();
AllFilesPath("/mnt/usb/");
playList();
}else{
Toast.makeText(this,"未檢測到U盤,請在開機前插入U盤,或者重新啟動此應用",Toast.LENGTH_SHORT).show();
Handlerhandler=newHandler();
handler.postDelayed(newRunnable(){
@Override
publicvoidrun(){
finish();
}
},2500);
}
}catch(Exceptione){
e.printStackTrace();
}
}
//獲取所有圖片視頻的絕對路徑到arraylist
privateArrayListAllFilesPath(Stringpath){
Filefile=newFile(path);
File[]files=file.listFiles();
for(Filef:files){
if(f.getName().endsWith("jpg")||f.getName().endsWith("jpeg")||f.getName().endsWith("mp4")
||f.getName().endsWith("avi")||f.getName().endsWith("mkv")||f.getName().endsWith("rmvb")
||f.getName().endsWith("flv")){
System.out.println("------------獲取到了一個可用路徑:"+f.getAbsolutePath());
arrayList.add(f.getAbsolutePath());//添加到arralist
}elseif(f.isDirectory()){
AllFilesPath(f.getAbsolutePath());
}
}
returnarrayList;
}
//依次混合播放arralist里的圖片或視頻
publicintlistNum;
privatevoidplayList(){
if(listNum>=arrayList.size()){
finish();
//listNum=0;
}else{
System.out.println("---------------------------收入路徑---------------------------");
System.out.println("isplaying="+isPlaying);
finalFilef=newFile(arrayList.get(listNum).toString());
if(f.getName().endsWith("jpg")||f.getName().endsWith("jpeg")||f.getName().endsWith("png")){
System.out.println("---------------------------添加了一張圖片:"+f.getAbsolutePath());
pictureView.setVisibility(View.VISIBLE);
pictureView.setImageURI(Uri.fromFile(f));
Handlerhandler=newHandler();
handler.postDelayed(newRunnable(){
@Override
publicvoidrun(){
System.out.println("---------------------------播完了一張位於"+f.getAbsolutePath()+"的圖片》》》》》》》》》》》》》》》》》");
pictureView.setVisibility(View.GONE);
listNum++;
playList();
}
},2000);//2秒後結束當前圖片
}elseif(f.getName().endsWith("mp4")||f.getName().endsWith("avi")||f.getName().endsWith("mkv")
||f.getName().endsWith("rmvb")||f.getName().endsWith("flv")){
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~添加了一個視頻"+f.getAbsolutePath());
videoView.setVideoPath(f.getAbsolutePath());
videoView.setVisibility(View.VISIBLE);//播放之前顯示videoView
videoView.start();
videoView.setOnCompletionListener(newMediaPlayer.OnCompletionListener(){
@Override
publicvoidonCompletion(MediaPlayermp){
System.out.println("---------------------------播完了一個位於"+f.getAbsolutePath()+"的視頻《《《《《《《《《《《《《《《《《《");
videoView.setVisibility(View.GONE);//視頻播放完畢後隱藏videoView
listNum++;
playList();
}
});
}
}
}
⑵ Android如何播放mov格式的視頻文件
Android播放「mov」格式的視頻文件時,可以藉助第三方軟體將「mov」格式轉換成「mp4」。
此處以微信為例,具體步驟如下:
1、打開安卓手機的微信軟體,點開任意聊天框將「mov」格式的視頻發送過去。
MP4與MOV的區別:
「mp4」格式的視頻相比起「mov」格式的視頻體積要小得多,前者格式壓縮率相比後者要大得多,雖然相對來說更省存儲空間,但畫質將會受到影響,很不利於後期編輯和製作,尤其是後期特效和調色。
這一點很像數碼相機的RAW格式和jpeg格式,前者為無損壓縮格式後者則是有損壓縮格式,前者的後期調整餘地更大。這也是很多資深的攝影者更願意用前者拍攝的原因。
⑶ android如何實現視頻的在線播放
vitamio
能播放絕大部分格式的視頻,但是這個有點大,裡面的so文件比較多,官方文檔上說有瘦身的方法,我試過但是沒成功,就一個用了vitamio
的小demo,打完包都10m了。在線視頻的話如果在電腦瀏覽器上能直接播放的話,用這個都可以播的,也有緩沖。我們項目也有在線視頻播放,原本也是准備用vitamio
的,但是太大了,打完包apk增加了10m,然後我就換成了universalvideoview
了,這個也可以在線播放,有緩沖效果,主要是打包後apk不大。如果你播放在線視頻功能要求高,而且不在乎apk大小的話可以使用vitamio
,如果僅想實現在線播放的話建議universalvideoview
就夠了!
⑷ 安卓視頻播放(阿里雲視頻點播播放器SDK+SurfaceView)
本篇文章講述使用阿里雲視頻視頻播放sdk中的高級播放器加上SurfaceView實現,採用id+STS方法進行視頻播放。
流程:用戶App獲取STS憑證 -> 服務端下發STS憑證 -> 用戶上傳視頻並獲取vid -> 服務端獲取STS憑證 -> 將STS憑證下發給客戶端 -> 完成視頻播放。
請看阿里雲文檔=========》》》》》》 阿里雲-高級播放器Android使用說明
接下來我們來看一下安卓給我們提供的手勢控制類
介面
setOnTouchListener(this);
其中定義了四種狀態 NONE = 0, VOLUME = 1, BRIGHTNESS = 2, FF_REW = 3;
接下來我們來看一下我們自定義的SurfaceViewOnGestureListener繼承 GestureDetector.SimpleOnGestureListener主要用到了
onDown(MotionEvent e)
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)兩個方法
a.在onDown的時候把狀態設置NONE
b.判斷橫向滑動的距離大於縱向滑動的距離,就把模式賦值為快進和後退
c.在onScroll中進行狀態賦值,根據滑動的距離,如果按下的點在屏幕的左半部分就吧狀態設置為調節亮度BRIGHTNESS,如果在右半部分就是調節音量
d.各種情況調用各自的介面方法
快進和後退,我們需要知道的就是我們滑動的距離如何與視頻的長度關聯起來。
那麼咱們就可以把視頻的總長度與屏幕的總長度相比,這樣就能知道你手指滑動的距離占視頻的多少了。
我們可以通過 l = ration / mySurfaceView.getWidth();來獲得這個比例,然後用當前的進度加上指滑動的距離占視頻的長度就是要播放的視頻位置
抬起點的x坐標與按下點的X坐標所得的距離,大於0是快進,小於零是後退。
系統的音量有很多,包括通話音量值,系統鈴聲值,音樂音量值,鬧鈴音量值,等等吧。
做一下筆記以備以後用到
視頻播放我們用的是音樂音量值,同樣的道理,我們需要把音量和高度進行關聯,我們可以控制項的高度閉上最大音量得出比例後就可以知道你滑動的距離占音量的多少了。
這里有個注意點就是activity是當前的這個界面,設置的是當前的界面,離開這個界面後就不管用了。
相同的道理和滑動調節音量一樣也是獲得屏幕的高度比上最大的亮度,然後計算滑動的距離轉換成亮度是多少。(這里不多講了)
為什麼會出現黑屏,就是按Home鍵再點App回來後,只有聲音沒有圖片的問題,因為我們用的是SurfaceView,每次點擊Home鍵時會銷毀這個SurfaceView,再回來時又會重新創建,這樣我們的阿里雲播放器與SurfaceView就沒有綁定了,畫面就沒有了。
這樣我們需要 給surfaceView添加mySurfaceView.getHolder().addCallback(this);
我們在按home鍵的時候會走surfaceDestroyed。這樣,我們就可以在這里做一個標識,讓他暫停,然後再回來的時候就會走surfaceCreated,判斷標識,然後進行處理就可以了。切記一定要重新讓aliyunVodPlayer與SurfaceView進行關聯,這樣才能有畫面也有聲音。
由於我們的視頻在阿里雲的伺服器上存著,訪問阿里雲的伺服器需要臨時憑證,我們通過STS來獲取Token,但是這個Token是有時間限制,正好阿里雲的播放器給我們提供了播放視頻出錯時候的回調介面,我們只需要在這裡面進行重新請求Token就可以了