android獲取視頻時長
⑴ android mediaplayer 可以設置播放時間嗎
MediaPlayer (1) 當一個MediaPlayer對象被創建或者調用reset()方法之後,它處於空閑狀態,調用release()方法後處於結束狀態 1,一個MediaPlayer對象調用了reset()方法後,再調用其它方法可能會觸發OnErrorListener.onError()事件,未調用reset()方法則不會觸發 2,當Mediaplayer對象不再被使用時,最好調用release()方法對其進行釋放,使其處於結束狀態,此時它不能被使用 3,Mediaplayer對象被創建時(調用構造方法)處於空閑狀態,若使用create()方法創建後則處於准備狀態。 (2) 一般情況下,一些常用的播放控制操作可能因為音頻、視頻的格式不被支持或者質量較差以及流超時,也有可能由於開發者的疏忽使得Mediaplayer對象處於無效狀態等而導致錯誤。此時可通過注冊setOnErrorListener方法實現監控。如果發生了錯誤,Mediaplayer對象將處於多霧狀態,可以使用reset()方法來回復錯誤。 (3) 任何Mediaplayer對象都必須先處於准備狀態,然後才開始播放 (4) 要開始播放Mediaplayer對象都必須成和陵賣功調用start()方法,可通過isPlaying()方法來檢測是否正在播放 (5) 當Mediaplayer對象在播放時,可以進行暫停和停止操作,pause()方法暫停播放,stop()方法停止播放。處於暫停暫停時可通過start()方法恢復播放,但是處於停止狀態時則必須先調用prepare()方法使其處於准備狀態,再調用start()方法。 主要方法: Mediaplayer:構造方法 create: 創建一個要播放的多媒體 getCurrentPosition:得到當前播放位置 getDuration: 得到文件的時間 prepare: 准備(同喚逗步) prepareAsync:准備(非同步) seekTo: 指定播放的位置(以毫秒為單位) setAudioStreamType: 設置流媒體的類型 setDataSource: 設置數據來源 setDisplay: 設置用SurfaceHolder來顯示多媒體 setOnBufferingUpdateListener: 網路流媒體的緩沖監聽 setOnErrorListener: 設置錯誤信息監聽 setOnVideoSizeChangedListener:視頻尺寸監聽 setScreenOnWhilePlaying: 設置是否使用SurfaceHolder來顯示 setVolume: 設置音量 //獲取sd卡上的音頻文件 setDataSource(「/sdcard/test.mp3」); //裝載資源中的音樂 MediaPlayer.create(Activity01.this,R.raw.test); //目前存在問題,不能循環解析出音頻文件 原因:.android_secure文件夾受保護,無法獲取汪姿裡面的文件信息 播放視頻 相關類:VideoView 方法說明: getBufferPercentage:得到緩沖的百分比 getCurrentPosition:得到當前播放位置 getDuration:得到視頻文件的時間 resolveAdjustedSize:調整視頻顯示大小 setMediaController:設置播放控制器模式(播放進度條) setOnCompletionListener:當視頻文件播放完時觸發事件 setVideoPath:設置視頻源路徑 setVideoURI:設置視頻源地址 錄音 相關類:MediaRecorder 方法說明: MediaRecorder:構造方法 getMaxAmplitude:得到最大幅度 setAudioEncoder:設置音頻編碼 setAudioSource:設置音頻源 setCamera:設置攝像機 setMaxDuration:設置最長錄音時間 setMaxFileSize:設置文件的最大尺寸 setOutputFile:設置輸出文件 setOutputFormat:設置輸出文件格式 setPreviewDisplay:設置預覽 setVideoEncoder:設置視頻編碼 setVideoFrameRate:設置視頻幀的頻率 setVideoSize:設置視頻的寬度和高度(解析度) setVideoSource:設置視頻源 File類下的方法: public static File createTempFile(String prefix, String suffix, File directory) Creates an empty temporary file in the given directory using the given prefix and suffix as part of the file name. 系統會自動在prefix和suffix之間加上一些數字來構建完整的文件名 實現錄音的一般步驟: 1, 實例化MediaRecorder mr,調用構造方法 2, 初始化mr:mr.setAudioSource(MIC)/setVideoSource(CAMERA) 3, 配置DataSource:設置輸出文件格式/路徑,編碼器等 4, 准備錄制:mr.prepare() 5, 開始錄制:mr.start() 6, 停止錄制:mr.stop() 7, 釋放資源:mr.release() 註:2,3不可調換順序 添加許可: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"> 相機設置 相關類:Camera,它是專門用來連接和斷開相機服務的類 Camera的幾個事件: Camera.AutoFocusCallback: 自動調焦功能 Camera.ErrorCallback: 錯誤信息捕捉 Camera.Parameters: 相機的屬性參數 Camera.PictureCallback: 拍照、產生圖片時觸發 Camera.PreviewCallback: 相機預覽設置 Camera.ShutterCallback: 快門設置 Camera.Size: 圖片的尺寸 Camera類沒有構造方法,可通過open()方法來打開相機設備 Camera類的方法介紹: autoFocus: 設置自動對焦 getParameters: 得到相機參數 open: 啟動相機服務 release: 釋放相機服務 setParameters: 設置參數 setPreviewDisplay:設置預覽 startPreview: 開始預覽 stopPreview: 停止預覽 takePicture: 拍照 註:takePicture方法要實現3個回調函數作為它的三個參數:Camera.ShutterCallback(快門),和兩個Camera.Picture.Callback(圖像數據)。 需要許可 <uses-permission android:name="android.permission.CAMERA" /> 若要將圖片存儲至sd卡中,則需要sd卡讀寫許可 目前存在問題:只能拍照一次,不能重新回到預覽界面 鬧鍾設置 相關類:AlarmManager,它是專門用來設定在某個指定的時間去完成指定的事件。AlarmManager提供了訪問系統警報的服務,只要在程序中設置了警報服務,AlarmManager就會通過onReceive()方法去執行這些事件,就算系統處於待機狀態,同樣不會影響運行。可通過Context.getSystemService(ALARM_SERVICE)方法來獲得該服務。 方法說明: cancel: 取消AlarmManager服務 set: 設置AlarmManager服務 setInexactRepeating:設置不精確周期 setRepeating:設置精確周期 setTimeZone:設置時區 註:需創建一個BroadcastReceiver的子類,並覆蓋onReceive()方法 鈴聲設置 系統自帶的鈴聲都放在/system/medio/audio/文件夾中 鈴音類型: TYPE_RINGTONE(來電鈴音),TYPE_ALARM,TYPE_NOTIFICATION 相關類:RingtoneManager 方法介紹: getActualDefaultRingtoneUri:取得指定類型的鈴聲 getCursor:返回所有可用鈴聲的游標 getDefaultType:得到指定URI默認的鈴聲類型 getRingtone getRingtonePosition:得到鈴聲位置 getRingtoneUri getValidRingtoneUri:得到一個可用鈴聲的URI isDefault:得到指定的Uri是否為默認的鈴聲 setActualDefaultRingtoneUri:設置默認的鈴聲 獲取的Cursor共有4列,列名依次為:_id,title,」content://media/internal/audio/media」,title_key 以設置手機鈴音為例: if (isFolder(strRingtongFolder)) {//如果不存在該文件夾則創建一個 // 打開系統鈴聲設置 Intent intent = new Intent( RingtoneManager.ACTION_RINGTONE_PICKER); intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, true); // 類型為來電ringtong intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE); // 設置顯示的題目 intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "設置來電的鈴聲"); // 當設置完成之後返回到當前的activity startActivityForResult(intent, RingtongButton); } 然後復寫onActivityResult(int requestCode, int resultCode, Intent data)方法,resultCode就是點擊設置dialog的按鈕編號,需要判斷是否點擊了確認按鈕 if (resultCode != RESULT_OK) { return; } try { // 得到我們選擇的鈴聲 Uri pickedUri = data .getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); // 將我們選擇的鈴聲選擇成默認 if (pickedUri != null) { RingtoneManager.setActualDefaultRingtoneUri( Media_RingTongActivity.this, RingtoneManager.TYPE_RINGTONE, pickedUri); } } catch (Exception e) { e.printStackTrace(); }
⑵ android中怎麼用SeekBar控制視頻播放的進度
android中用SeekBar控制視頻播放的進度其實現方法如下:
1:第一個類是自定義的一個類 也就是SeekBar上方會跟隨其一塊移動的控制項,其實非常簡單的一個類
package com.example.textmovebyseekbar;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
//import android.widget.AbsoluteLayout;
public class TextMoveLayout extends ViewGroup {
public TextMoveLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public TextMoveLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public TextMoveLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
}
?
2: 第二類就是MainActivity了,代碼很簡單!
package com.example.textmovebyseekbar;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends Activity {
private SeekBar seekbar = null;
private String startTimeStr = "19:30:33";
private String endTimeStr = "21:23:21";
private TextView text, startTime, endTime;
/**
* 視頻組中第一個和最後一個視頻之間的總時長
*/
private int totalSeconds = 0;
/**
* 屏幕寬度
*/
private int screenWidth;
/**
* 自定義隨著拖動條一起移動的空間
*/
private TextMoveLayout textMoveLayout;
private ViewGroup.LayoutParams layoutParams;
/**
* 托動條的移動步調
*/
private float moveStep = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_fast_search);
screenWidth = getWindowManager().getDefaultDisplay().getWidth();
text = new TextView(this);
text.setBackgroundColor(Color.rgb(245, 245, 245));
text.setTextColor(Color.rgb(0, 161, 229));
text.setTextSize(16);
layoutParams = new ViewGroup.LayoutParams(screenWidth, 50);
textMoveLayout = (TextMoveLayout) findViewById(R.id.textLayout);
textMoveLayout.addView(text, layoutParams);
text.layout(0, 20, screenWidth, 80);
/**
* findView
*/
seekbar = (SeekBar) findViewById(R.id.seekbar);
startTime = (TextView) findViewById(R.id.start_time);
endTime = (TextView) findViewById(R.id.end_time);
/**
* setListener
*/
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListenerImp());
searchVideos();
}
public void searchVideos() {
startTime.setText(startTimeStr);
endTime.setText(endTimeStr);
text.setText(startTimeStr);
totalSeconds = totalSeconds(startTimeStr, endTimeStr);
seekbar.setEnabled(true);
seekbar.setMax(totalSeconds);
seekbar.setProgress(0);
moveStep = (float) (((float) screenWidth / (float) totalSeconds) * 0.8);
}
private class OnSeekBarChangeListenerImp implements
SeekBar.OnSeekBarChangeListener {
// 觸發操作,拖動
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
text.layout((int) (progress * moveStep), 20, screenWidth, 80);
text.setText(getCheckTimeBySeconds(progress, startTimeStr));
}
// 表示進度條剛開始拖動,開始拖動時候觸發的操作
public void onStartTrackingTouch(SeekBar seekBar) {
}
// 停止拖動時候
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
/**
* 計算連個時間之間的秒數
*/
private static int totalSeconds(String startTime, String endTime) {
String[] st = startTime.split(":");
String[] et = endTime.split(":");
int st_h = Integer.valueOf(st[0]);
int st_m = Integer.valueOf(st[1]);
int st_s = Integer.valueOf(st[2]);
int et_h = Integer.valueOf(et[0]);
int et_m = Integer.valueOf(et[1]);
int et_s = Integer.valueOf(et[2]);
int totalSeconds = (et_h - st_h) * 3600 + (et_m - st_m) * 60
+ (et_s - st_s);
return totalSeconds;
}
/**
* 根據當前選擇的秒數還原時間點
*
* @param args
*/
private static String getCheckTimeBySeconds(int progress, String startTime) {
String return_h = "", return_m = "", return_s = "";
String[] st = startTime.split(":");
int st_h = Integer.valueOf(st[0]);
int st_m = Integer.valueOf(st[1]);
int st_s = Integer.valueOf(st[2]);
int h = progress / 3600;
int m = (progress % 3600) / 60;
int s = progress % 60;
if ((s + st_s) >= 60) {
int tmpSecond = (s + st_s) % 60;
m = m + 1;
if (tmpSecond >= 10) {
return_s = tmpSecond + "";
} else {
return_s = "0" + (tmpSecond);
}
} else {
if ((s + st_s) >= 10) {
return_s = s + st_s + "";
} else {
return_s = "0" + (s + st_s);
}
}
if ((m + st_m) >= 60) {
int tmpMin = (m + st_m) % 60;
h = h + 1;
if (tmpMin >= 10) {
return_m = tmpMin + "";
} else {
return_m = "0" + (tmpMin);
}
} else {
if ((m + st_m) >= 10) {
return_m = (m + st_m) + "";
} else {
return_m = "0" + (m + st_m);
}
}
if ((st_h + h) < 10) {
return_h = "0" + (st_h + h);
} else {
return_h = st_h + h + "";
}
return return_h + ":" + return_m + ":" + return_s;
}
}
3: 接下來這個就是布局文件了,其中會用到一些色值!
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_whitef5"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.example.textmovebyseekbar.TextMoveLayout
android:id="@+id/textLayout"
android:layout_width="fill_parent"
android:layout_height="40dp" />
<SeekBar
android:id="@+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:maxHeight="4dp"
android:minHeight="4dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:progressDrawable="@drawable/po_seekbar"
android:thumb="@drawable/seekbar_thumb" />
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/start_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="14dp"
android:textColor="@color/bg_lin_95" />
<TextView
android:id="@+id/end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="14dp"
android:textColor="@color/bg_lin_95" />
</RelativeLayout>
</LinearLayout>
4: android:progressDrawable="@drawable/po_seekbar"這句會引用一個xml文件
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@*android:id/background">
<shape>
<solid android:color="#c6c6c6" />
</shape>
</item>
<item android:id="@*android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#c6c6c6" />
</shape>
</clip>
</item>
<item android:id="@*android:id/progress">
<clip>
<shape>
<solid android:color="#06a7fa" />
</shape>
</clip>
</item>
</layer-list>
5:android:thumb="@drawable/seekbar_thumb"也會引用一個xml文件 這其中又有用到兩張圖片
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/video_fast_search_nomal" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="@drawable/video_fast_search_press" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="@drawable/video_fast_search_press" android:state_focused="false" android:state_pressed="true"/>
<item android:drawable="@drawable/video_fast_search_nomal"/>
</selector>
⑶ android獲取視頻每一幀
本周給大家分享如何獲取視頻的每一幀的信息,說到這個那就得看我們的谷歌官方給我們的提供的api介面類:MediaMetadataRetriever,這個類是提供給我們用來獲取視頻信息的,
官方文檔:
https://developer.android.google.cn/reference/android/media/MediaMetadataRetriever
通過文檔我們知道,我們可以通過它提供的extractMetadata()方法獲取視頻基本信息,
例如:視頻寬、高,時長,作者等,還有通過getFrameAtTime()方法獲取對應時長位置的視頻幀信息,返回的是一個bitmap對象
通過實踐知道,這個方法好是好,但是獲取視頻幀的速度太慢了,我自己做的實驗是,獲取一個4分多鍾的視頻,每隔10秒取一幀,開了4個線程去取,時間大概在10秒左右,這樣對於我們來說是不可以忍受的,所以最後在github上找到了一個很好的庫推薦給大家:
https://github.com/wseemann/FFmpegMediaMetadataRetriever
這個庫是基於ffmpeg實現的,同樣的實驗獲取視頻幀信息的速度在1秒左右,只開了一個線程,ffmpeg還是依舊的強大啊。
通過本周的學習,自己對於ffmpeg是越來越趕興趣了,所以買了一本書來研究一下,但是本書講的都是c語言,所以沒辦法又把我大學學習的c語言的書找了出來,繼續開始著自己的爬坑之旅。
⑷ 【Android音視頻】MediaMetadataRetriever使用
MediaMetadataRetriever是Android原生提供的獲取音視頻文件信息的一個類,我們可以通過這個類的相關方法獲取一些基本信息,如視頻時長、寬高、幀率、方向、某一幀的圖片等。
我們可以通過MediaMetadataRetriever的extractMetadata(int keyCode)的方法獲取一些視頻的基本信息,以下列出一些常用的:
可以通過getFrameAtTime(long timeUs)獲取某一時刻附近的幀圖片;API>=28,可以准確獲取幀圖片,相關方法getFrameAtIndex(...);獲取幀圖可以應用在 視頻封面圖 、 視頻裁剪的縮略圖 等。
MediaMetadataRetriever還是比較常用的,以上只是簡略的列出了MediaMetadataRetriever的一些用法,具體可自行查閱源文件。
⑸ Android中如何截獲第三方媒體播放器中正在播放的音樂或視頻的當前播放時間進度和總時間求高手指點
java">//音樂的總長賣滑度
intmax=media.getDuration();
//獲取吵配胡當前音樂播放升攔位置
intcurrent=media.getCurrentPosition();
⑹ Android錄制視頻,可限制時長,限大小
Android 錄制視頻:
public static voidrecordVideo(Context context, intlimit_time, intsize) {
Intent intent =newIntent();
intent.setAction(MediaStore. ACTION_VIDEO_CAPTURE );
intent.putExtra(MediaStore. EXTRA_VIDEO_QUALITY ,1);
intent.addCategory(Intent. CATEGORY_DEFAULT );
if(size !=0) {
//大小限制是long型,int 型無效,所以後邊要寫一個L
intent.putExtra(MediaStore. EXTRA_SIZE_LIMIT ,size *1024*1024L);//限制錄制大小(10M=10 * 1024 * 1024L)
}
if(limit_time !=0) {
intent.putExtra(MediaStore. EXTRA_DURATION_LIMIT ,limit_time);//限制錄制時間(10秒=10)
}
File videoFile =createVideoFile(context);
if(videoFile !=null) {
intent.putExtra(MediaStore. EXTRA_OUTPUT ,Uri.fromFile(videoFile));
context.startActivityForResult(intent, CAPTURE_VIDEO_CODE );
}
}
⑺ uc瀏覽器Android版,如何緩存<1min的短視頻
不是所有的手機視頻都能使用uc瀏覽器緩存的,微博視頻來說,直接發布的秒拍是不可以緩存只能在線觀看的,如果是通過秒拍的軟體或者嗶哩嗶哩動畫的軟體等分享到微博的就可以用uc緩存。
如果你要下載的視頻是通過其他的視頻軟體比如秒拍app發布的,就可以下載,這類視頻的正文中有一個視頻圖標。點擊該圖標進入秒拍視頻界面。
進入秒拍後,右上方有分享按鈕(「…」圖標),此時出現菜單,選擇復制鏈接,復制鏈接後進入uc瀏覽器,長按粘貼鏈接,下面出現粘貼並進入,進入後uc瀏覽器界面顯示視頻。
中間的視頻播放小窗口出現下載按鈕,點擊下載按鈕後會出現添加到緩存任務,此時,點擊手機屏幕左鍵出現「菜單—我的視頻」,正在緩存中出現該視頻。
打開秒拍視頻後也可以採用直接瀏覽器打開的方式,同樣點擊分享圖標,點擊「瀏覽器打開」
對於不是秒拍的其他視頻app,例如b站有的可以選擇瀏覽器打開,選擇uc瀏覽器打開,此時在uc界面顯示其他網頁,同樣點擊下載圖標進行下載操作。
因為這種情況下很多視頻名稱無法自動識別,在視頻很多的情況下,大家在已經緩存的視頻中找到視頻進行重命名,短按視頻,出現重命名,修改名稱。
如果是不需要從外部鏈接打開的視頻,直接在uc上打開的視頻,點開後是直接可以下載的,專輯是有下載菜單的,點擊下載即可。很方便的。緩存完成是視頻是.vdat格式的。
⑻ Android實現視頻播放的幾種方式
Android提供了常見的視頻編碼,解碼機制,使用Android自帶的MediaPlayer,MediaController等類可以很方便的實現視頻播放的功能。支持的視頻格式有MP4和3GP等。這些多媒體數據可以來自於Android應用的資源文件,也可以來自於外部存儲器上的文件,甚至可以是來自於網路上的文件流。
1、MediaController+VideoView實現方式
這種方式是最簡單的實現方式。VideoView繼承了SurfaceView同時實現了MediaPlayerControl介面,MediaController則是安卓封裝的輔助控制器,帶有暫停,播放,停止,進度條等控制項。通過VideoView+MediaController可以很輕松的實現視頻播放、停止、快進、快退等功能。
布局文件如下:
使用此實現方式的步驟:
1.載入指定的視頻文件
2.建立VideoView和MediaController之間的關聯,這樣就不需要自己去控制視頻的播放、暫停等。讓MediaController控制即可。
3.VideoView獲取焦點。
2、MediaPlayer+SurfaceView+自定義控制器
雖然VideoView的實現方式很簡單,但是由於是自帶的封裝好的類,所以無論是播放器的大小、位置以及控制都不受我們控制。
這種實現方式步驟如下:
1.創建MediaPlayer對象,並讓它載入指定的視頻文件。可以是應用的資源文件、本地文件路徑、或者URL。
2.在界面布局文件中定義SurfaceView組件,並為SurfaceView的SurfaceHolder添加Callback監聽器。
3.調用MediaPlayer對象的setDisplay(SurfaceHolder sh)將所播放的視頻圖像輸出到指定的SurfaceView組件。
4.調用MediaPlayer對象的prepareAsync()或prepare()方法裝載流媒體文件
5.調用MediaPlayer對象的start()、stop()和pause()方法來控制視頻的播放。
在實現第二步之前需要先給surfaceHolder設置一個callback,callback的3個回調函數如下:
3、MediaPlayer+SurfaceView+MediaController
第二種實現方式使用的是自定義控制項,MediaPlayer+SurfaceView也可以使用系統自帶的MediaController控制器。
使用這個方式實現,布局文件只需一個SurfaceView即可,其他的控制項都交給MediaController控制器,布局文件如下:
實際過程中推薦大家使用B站的播放器ijkplayer非常好用!