Android多媒體之視訊播放器高階開發
1.獲取播放的資料來源
播放視訊的資料來源一般有兩個,一個是請求網路,從伺服器後臺直接獲取播放的視訊資訊,另一種是播放手機中本地的視訊,這裡我們採用的播放源為播放手機本地的視訊
1.1 查詢獲取手機中的視訊的資訊
1.1.1 查詢方法一
定義要查詢到的視訊的資訊,包括視訊的名稱,視訊大小,視訊播放時長以及在手機中的儲存位置
String[] projection = {Media._ID,Media.TITLE,Media.SIZE,Media.DURATION,Media.DATA};
進行資料的查詢操作
Cursor cursor = getActivity().getContentResolver().query(Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
這裡查詢到的資訊是包含在cursor物件中的
1.1.2 查詢方法二
SimpleQueryHandler queryHandler = new SimpleQueryHandler(getActivity().getContentResolver()); String[] projection = {Media._ID,Media.TITLE,Media.SIZE,Media.DURATION,Media.DATA}; queryHandler.startQuery(0, adapter, Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
public class SimpleQueryHandler extends AsyncQueryHandler{ public SimpleQueryHandler(ContentResolver cr) { super(cr); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { super.onQueryComplete(token, cookie, cursor); if(cookie!=null && cookie instanceof CursorAdapter){ CursorAdapter adapter = (CursorAdapter) cookie; adapter.changeCursor(cursor);//相當於notify } } }
邊裡是呼叫的非同步查詢的方法,查詢到的視訊的相關資訊也是包含在cursor中的,其中傳入的adapter物件是繼承於CursorAdapter
1.1.3 建立儲存視訊資訊的info物件
public class VideoItem implements Serializable{
public String title;//視訊的名稱
public long size;//視訊的大小
public long duration;//視訊的時長
public String path;//視訊在手機中的路徑
/**
* 將cursor中的資料封裝為一個info
* @param cursor
* @return
*/
public static VideoItem fromCursor(Cursor cursor){
VideoItem videoItem = new VideoItem();
videoItem.duration=cursor.getLong(cursor.getColumnIndex(Media.DURATION)));
videoItem.path=cursor.getString(cursor.getColumnIndex(Media.DATA)));
videoItem.size=cursor.getLong(cursor.getColumnIndex(Media.SIZE)));
videoItem.title=cursor.getString(cursor.getColumnIndex(Media.TITLE)));
return videoItem;
}
}
2.以列表的方式將視訊資訊顯示出來
2.1 建立資料介面卡
這裡使用到的是ListView來設定顯示資料,所以需要給ListView準備一個介面卡,來設定顯示資料,由於我們查詢到的資料是封裝在Cursor中的,所以我們這裡可以建立繼承於CursorAdapter的介面卡
public class VideoListAdapter extends CursorAdapter{
public VideoListAdapter(Context context, Cursor c) {
super(context, c);
}
/**
* 直接從佈局中載入view返回,這裡就是ListView中顯示的item佈局,可以自定義隨便佈局
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return View.inflate(context, R.layout.adapter_video_list, null);
}
ViewHolder holder;
/**
* 將資料設定給view
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
holder = getHolder(view);
//獲取資料,這裡的資料是儲存在cursor中,通過方法fromCursor直接轉換成VideoItem物件儲存的資訊
VideoItem videoItem = VideoItem.fromCursor(cursor);
holder.tv_title.setText(videoItem.title);
//這裡獲取到的時長是毫秒,可以通過 自定義的時間格式來對時間進行格式化操作
holder.tv_duration.setText(StringUtil.formatVideoDuration(videoItem.duration()));
//將視訊的大小格式化為M來進行資料顯示
holder.tv_size.setText(Formatter.formatFileSize(context, videoItem.size()));
}
private ViewHolder getHolder(View view){
ViewHolder viewHolder = (ViewHolder) view.getTag();
if(viewHolder==null){
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
}
return viewHolder;
}
class ViewHolder{
TextView tv_title,tv_duration,tv_size;
public ViewHolder(View view){
tv_title = (TextView) view.findViewById(R.id.tv_title);
tv_duration = (TextView) view.findViewById(R.id.tv_duration);
tv_size = (TextView) view.findViewById(R.id.tv_size);
}
}
}
2.2 為ListView設定顯示資料
VideoListAdapter adapter = new VideoListAdapter(getActivity(), null);
listView.setAdapter(adapter);
注:到這裡,我們就 可以將手機中的視訊的資訊顯示到一個ListView中了
3.點選資訊條目,跳轉到視訊播放頁面
3.1 為ListView設定條目的點選事件,並獲取到相應位置的視訊資訊
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//獲取當前點選的條目對應的資料
Cursor cursor = (Cursor) adapter.getItem(position);
Bundle bundle = new Bundle();
//當前點選播放視訊的位置
bundle.putInt("currentPosition", position);
//視訊資訊的集合
bundle.putSerializable("videoList", cursorToList(cursor));
Intent intent = new Intent(getActivity(),VitamioPlayerActivity.class);
intent.putExtras(bundle);
getActivity().startActivity(intent);
}
});
其中呼叫了一個方法,是將cursor中的資料轉換成集合中儲存物件的方法儲存資訊,以方便資料的傳遞
private ArrayList<VideoItem> cursorToList(Cursor cursor){
ArrayList<VideoItem> list = new ArrayList<VideoItem>();
cursor.moveToPosition(-1);
while(cursor.moveToNext()){
list.add(VideoItem.fromCursor(cursor));
}
return list;
}
其中呼叫的VideoItem.fromCursor方法是物件中封裝的轉換cursor物件資料的方法
4.視訊播放頁面
4.1 獲取傳遞過來的視訊資訊
private int currentPosition;//當前播放視訊的位置
private ArrayList<VideoItem> videoList;//當前的視訊列表
currentPosition = getIntent().getExtras().getInt("currentPosition");
videoList = (ArrayList<VideoItem>) getIntent().getExtras().getSerializable("videoList");
4.2 設定視訊播放並設定監聽
這裡使用到的是控制元件VideoView,
//設定播放的資料
playVideo();
//設定進行播放的操作監聽
video_view.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//進行視訊的播放
video_view.start();
//更新視訊播放指示的進度條
updatePlayProgress();
//設定指示的進度條的最大值
video_seekbar.setMax((int) video_view.getDuration());
//設定顯示當前的播放時間
tv_current_position.setText("00:00");
//設定顯示視訊的總時長
tv_duration.setText(StringUtil.formatVideoDuration(video_view.getDuration()));
//設定播放按鈕的背景圖片
btn_play.setBackgroundResource(R.drawable.selector_btn_pause);
}
});
呼叫的方法playVideo
private void playVideo(){
//上一視訊的控制按鈕(如果是第一節,則不再點選)
btn_pre.setEnabled(currentPosition!=0);
//下一視訊的控制按鈕(如果是最後一節,則不再點選)
btn_next.setEnabled(currentPosition!=(videoList.size()-1));
//獲取當前位置對應的資料
VideoItem videoItem = videoList.get(currentPosition);
//設定頁面顯示的視訊標題
tv_name.setText(videoItem.getTitle());
//進行視訊的播放
video_view.setVideoURI(Uri.parse(videoItem.getPath()));
}
playVideo方法為videoview設定了播放的資料來源,當videoView載入準備好後,由於設定了監聽OnPreparedListener方法,所以會呼叫其中的onPrepared,在這裡進行開始播放視訊的操作,並可以獲取到當前要播放的視訊的總時長,以設定指示進度的進度條顯示的最大值,以及更新其他相關的UI等
4.3 設定點選播放上一節視訊的方法
btn_pre.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(currentPosition>0){
currentPosition - -;
playVideo();
}
}
});
btn_pre 是播放上一節視訊的觸發按鈕這裡的currentPosition是當前播放的視訊在視訊集合中的位置,呼叫playVideo,會將對應位置的視訊資訊獲取出來,然後設定給VideoView,然後當資源準備完成後,會呼叫到監聽OnPreparedListener中的onPrepared方法,來進行相應的視訊播放
4.4 設定點選播放下一節視訊的方法
btn_next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(currentPosition<(videoList.size()-1)){
currentPosition ++;
playVideo();
}
}
}
});
btn_next是播放下一節視訊的觸發按鈕,播放原理邏輯與播放上一節視訊內容是一致的
4.5 為播放視訊設定其他的相監聽
//當視訊播放完成時進行的操作監聽
video_view.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//例如可以更新播放進度的指示大小,以及其他相關的UI操作
}
});
//視訊緩衝進度的監聽
video_view.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
//percent:0-100
long bufferProgress = (long) ((video_view.getDuration()/100f)*percent);
//這裡設定顯示視訊緩衝進度條的顯示 video_seekbar 是指示視訊播放的進度條
video_seekbar.setSecondaryProgress((int) bufferProgress);
}
});
//視訊播放卡頓時進行的操作
video_view.setOnInfoListener(new OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_BUFFERING_START :
//開始卡頓 顯示緩衝載入的進度條
ll_buffer.setVisibility(View.VISIBLE);
break;
case MediaPlayer.MEDIA_INFO_BUFFERING_END :
//卡頓結束 隱藏緩衝載入的進度條
ll_buffer.setVisibility(View.GONE);
break;
}
return true;
}
});
//視訊播放錯誤的監聽
video_view.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN :
//未知格式,視訊檔案錯誤,進行相關資訊的提示
Toast.makeText(VitamioPlayerActivity.this, "視訊格式不支援", 0).show();
break;
}
return true;
}
});
}
4.6 對播放中指示播放進度的進度條(video_seekbar)的操作
4.6.1 指示快取進度的操作
在setOnBufferingUpdateListener這個監聽中操作了video_seekbar的快取進行更新
4.6.2 實時更新播放的指示進度
private void updatePlayProgress(){
//顯示當前的播放進度
tv_current_position.setText(StringUtil.formatVideoDuration(video_view.getCurrentPosition()));
//設定進度條的指示位置
video_seekbar.setProgress((int) video_view.getCurrentPosition());
handler.sendEmptyMessageDelayed(1, 500);
}
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
updatePlayProgress();
break;
};
};
可以看到,這裡使用的是handler訊息機制,迴圈傳送訊息
4.6.3 手動拖動進度條控制視訊播放的進度
video_seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser){
//fromUser =true;表示是使用者手動拖動
//播放相應位置的視訊
video_view.seekTo(progress);
//更新播放時間進度顯示
tv_current_position.setText(StringUtil.formatVideoDuration(progress));
}
}
});
4.7 對播放中指示播放音量的進度條操作
4.7.1 初始化顯示系統的音量
private AudioManager audioManager;
private int currentVolume;//系統音樂和視訊型別當前的音量
private boolean isMute = false;//是否是靜音模式
private int maxVolume;//系統中音樂和視訊型別最大音量
private SeekBar voice_seekbar;//顯示音量指示資訊的進度條
private void initVolume(){
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//maxVolume:0-15
maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
//設定音量指示進度條的最大指示進度
voice_seekbar.setMax(maxVolume);
//設定當前的音量大小對應的指示進度顯示
voice_seekbar.setProgress(currentVolume);
}
voice_seedbar 是視訊頁面指示播放音量大小的進度條
4.7.2 手動拖動進度條改變播放音量的大小
與拖動指示播放進度的進度條的方法一致
voice_seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser){//表示是使用者手動拖動
isMute = false;
//記錄當前的音量
currentVolume = progress;
//更新系統音量的操作
updateSystemVolume();
}
}
});
/**
* 更新系統音量
*/
private void updateSystemVolume(){
if(isMute){
//靜音模式,設定音量大小為0,並將指示音量大小的進度條進度設定為0
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
voice_seekbar.setProgress(0);
}else {
//設定當前改變到的音量大小的進度
voice_seekbar.setProgress(currentVolume);
//第三個引數如果是1,會顯示音量改變的浮動面板
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0);
}
}
4.7.3 手動上下滑動螢幕改變播放音量的大小
涉及到手勢操作,做一些初始化操作準備
int touchSlop = ViewConfiguration.getTouchSlop();
GestureDetector gestureDetector = new GestureDetector(this,new MyOnGestureListner());
可以在相關方法中做一些滑動過程中的操作
private class MyOnGestureListner extends SimpleOnGestureListener{
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return super.onDoubleTap(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return super.onSingleTapConfirmed(e);
}
}
捕捉觸控事件,並將事件傳遞給gestureDetector;
private float downY;
@Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveY = event.getY();
float moveDistance = moveY - downY;
//對滑動距離進行一個值的限制
if(Math.abs(moveDistance)<touchSlop)break;
isMute = false;
float totalDistance = Math.min(screenHeight, screenWidth);
float movePercent = Math.abs(moveDistance)/totalDistance;
int moveVolume = (int) (movePercent*maxVolume);//這個值一定是0
if(moveDistance>0){
//減小音量
currentVolume -= 1;
}else {
//增大音量
currentVolume += 1;
}
updateSystemVolume();
downY = moveY;
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(event);
}
相關推薦
Android多媒體之視訊播放器高階開發
1.獲取播放的資料來源 播放視訊的資料來源一般有兩個,一個是請求網路,從伺服器後臺直接獲取播放的視訊資訊,另一種是播放手機中本地的視訊,這裡我們採用的播放源為播放手機本地的視訊 1.1 查詢獲取手機中的視訊的資訊 1.1.1 查詢方法一 定義要查詢到的視訊的資訊,包括視
Android之視訊播放器的使用及解決的問題
前言 根據專案要求 做一個淘寶今日頭條的功能 要求實現圖文和視訊的混排 在之前的部落格中我已經寫了頭條滾動demo———今日頭條的demo地址 就是這樣的一個效果 點選這個控制元件後 進入↓↓↓頭條的頁面 這篇部落格主要是記錄視訊的使用 關於文
Android自定義視訊播放器(網路/本地)
最近因公司專案要求需要寫一個播放器,自帶的又不太好用,也不太好看。自能自定義啦。查看了很多資料,都沒有完善的,還好得以為前輩的指點得以完成,感謝Yang。本篇裡面我有可能有些地方寫得不好(都附上了註釋)。希望各路大神指點,虛心受教。 先來個圖(原始碼在後面附上) 視訊列表裡面
【Android SurfaceView】視訊播放器 簡單例子
找過好過視訊播放器的例子,但是都特麼給一半程式碼,不給一半程式碼! 還有的 我也是醉了!把自己以前的筆記發一下吧, 雖然有缺陷: 1,橫屏切換的時候,執行緒會死掉,不能啟用... (已經搞定了!謝謝各位dalao!) 2,停止的時候,執行緒釋放了資源,但是還是有一張圖片
Android自定義視訊播放器(三)
一、引言 在上文中,我們通過自定義控制面板的佈局,來實現自定義的播放控制,下面來對裡面的各個元件進行事件繫結。 @Override public void onClick(View v) { if ( v == btnVoice ) {
android 顯示flash視訊播放器
因專案需要在web view中能開啟網頁連結,但是有的網頁中包含了使用了flash的視訊播放器,如果是預設的web view 開啟這樣的網頁flash的位置為顯示為空白,根據網上查詢的資料通過以下方式可以解決(android 4.4): webSettings
Android筆記:視訊播放器播放本地視訊和網路視訊
這篇博文主要是記錄一下VideoView的使用,這個demo使用VideoView來播放本地視訊和網路視訊。 先來看一下效果圖: 接下來說程式碼: 1。佈局檔案: <?xml ve
Android自定義視訊播放器(六)
一、引言 現在已經差不多完成了一個自定義的視訊播放器,還有一個讓視訊全屏播放的按鈕事件沒有繫結,下面會介紹。此外還要一個非常重要的功能就是,已經寫好了自定義的播放器,那麼就應該能被其他應用調起,來播放視訊,下面來完善這兩個功能。 二、全屏按鈕事件
Android自定義視訊播放器(一)
一、引言 我們在開發Android多媒體應用時,有兩種方式來播放多媒體資源。第一種是使用隱式的Intent,來使用系統或者手機已經安裝的第三方播放器應用來播放音視訊,第二種是使用Android自帶的、我們自定義的播放器來播放,這種主要是採用Android提供的
Android系列之音樂播放器的實現一(播放手機記憶體音訊檔案)
現在給大家實現的是利用手機記憶體卡里的音訊檔案去播放的,至於xml佈局檔案大家可以去看我上一篇部落格的,因為這兩篇部落格是相關聯的。現在就開始吧!xml配置檔案許可權:(一定要加上) <uses-permission android:name="android.per
Android自定義視訊播放器(二)
一、引言 上一篇在對VideoView使用時,加上了這樣一行程式碼: videoView.setMediaController(new MediaController(this)); 這行程式碼為VideoView加上了控制面板,可以操作視訊播放的快
基於NDK、C++、FFmpeg的android視訊播放器開發實戰-夏曹俊-專題視訊課程
基於NDK、C++、FFmpeg的android視訊播放器開發實戰—1796人已學習 課程介紹 課程包含了對流媒體(拉流)的播放,演示了播放rtmp的香港衛視,支援rtsp攝像頭和h
Android簡單視訊播放器之VideoView(一)
早上起來有時間,發一篇博文,最近在開發電視機頂盒的視訊播放,涉及到Android當中比較常見的視訊播放器控制元件的使用,以此為例,記錄下來。 首先,上效果圖: 通過VideoView播放視訊的步驟: 實現方式:使用XML佈局和java程式碼控制元
三、VR視訊播放器開發 ---- Android VR視訊/Google VR for Android /VR Pano/VR Video
simplevideowidget 如果沒有看上一篇文章的請先看完再來看這一篇吧,有寫重複的就不介紹了 AndroidManifest 上一篇文章有提到,其實這裡也沒有什麼特別的 build.gradle dependencie
Android使用VLC庫開發自己的視訊播放器
clone完成之後,把工程目錄下的java_sample/src/main/java/org/videolan/javasample/JavaActivity.java拷貝至TestVideoPlayer工程videoPlayer目錄下,再新增必要的檔案之後,整個工程目錄如下:
安卓多媒體播放器的開發
lis list 媒體 ongl .com ava aid 多媒體 http JaVa%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6%E5%AE%9E%E7%8E%B0%E5%8F%8A%E5%8E%9F%E7%90%86 http://musi
android,Exoplayer實現視訊播放器
bundle配置: implementation 'com.google.android.exoplayer:exoplayer-core:2.8.1'implementation 'com.google.android.exoplayer:exoplayer-dash:2.8.1'implementati
關於使用OpenCV-python開發簡易視訊播放器
正在研究開簡易如何開發簡易視訊播放器,找了一些一列,包括在pyglet上面的程式碼,但是好長,執行出錯。 看到一個很簡潔的程式碼,沒有報錯但是彈開之後不會自動播放視訊,也沒有生成應用程式。 http://blog.51cto.com/7335580/2145914 這是他的連結,很簡潔
android形狀屬性、鎖屏密碼、動態模糊、kotlin專案、抖音動畫、記賬app、視訊播放器等原始碼
Android精選原始碼 直觀瞭解Android的“形狀”屬性如何影響Drawable的外觀。 一個靈活的視訊播放器, 可替換播放器核心。 android鎖屏輸入密碼功能原始碼 背景動態模糊方案,元件實現類對bitmap模糊處理的各類算... 簡單天氣,帶
android平臺下基於ffmpeg和ANativeWindow實現簡單的視訊播放器
音視訊實踐學習 android全平臺編譯ffmpeg以及x264與fdk-aac實踐 ubuntu下使用nginx和nginx-rtmp-module配置直播推流伺服器 android全平臺編譯ffmpeg合併為單個庫實踐 android-studio使用c