美文网首页
Android音视频开发之获取视频默认状态总时长

Android音视频开发之获取视频默认状态总时长

作者: 淡然灬一笑 | 来源:发表于2022-04-12 15:20 被阅读0次

    前言:

       Android中视频或者音频播放的话获取到播放进度和总时长是很常见的,最近有个需求需要在视频不播放时显示总时长,播放器默认状态的话是没有进度和时长的,调试断点发现时长总是为负数就感觉很不美妙了,本篇文章就是为了解决视频或音频默认状态下根据url获取视频的总时长。

    1.获取视频时长的方法如下:

    /**

    * 根据url查询视频时长和宽高

    *

    * @param url

    * @return

    */

    public static long getPlayTime(String url) {

       android.media.MediaMetadataRetriever metadataRetriever = new android.media.MediaMetadataRetriever();

       try {

           if (url != null) {

               HashMap<String, String> headers;

               headers = new HashMap<>();

               headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");

               metadataRetriever.setDataSource(url, headers);

           } else {

               //mmr.setDataSource(mFD, mOffset, mLength);

           }

           durationTime = Long.valueOf(metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));//时长(毫秒)

           String width = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽

           String height = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高

       } catch (Exception ex) {

           ex.printStackTrace();

       } finally {

           metadataRetriever.release();

       }

       return durationTime;

    }

    2.在项目中的实际使用:

    private void initData() {

       mHandler.postDelayed(new Runnable() {

           @Override

           public void run() {

               long time = VideoUtils.getPlayTime(videoUrl);

               Log.d("--time--",time+"");

               jzvdStd.totalTimeTextView.setText(JZUtils.stringForTime(time));

           }

       },200);

      getDuration(videoUrl);

    }

    3.出现问题:直接使用MediaMetadataRetriever,如果网络不好或者在列表中使用非常卡顿,会出现anr问题,解决方法:使用rxjava异步方式处理.

    使用rxjava方式代码如下:

       public void getDuration(String url){

           io.reactivex.Observable<Long> observable = io.reactivex.Observable.create(new ObservableOnSubscribe<Long>() {

               @Override

               public void subscribe(ObservableEmitter<Long> e) throws Exception {

                   android.media.MediaMetadataRetriever metadataRetriever = new android.media.MediaMetadataRetriever();

                   try {

                       if (url != null) {

                           HashMap<String, String> headers;

                           headers = new HashMap<>();

                           headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");

                           metadataRetriever.setDataSource(url, headers);

                       } else {

                           //mmr.setDataSource(mFD, mOffset, mLength);

                       }

                       long durationTime = Long.parseLong(metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));//时长(毫秒)

                       String width = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽

                       String height = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高

                       e.onNext(durationTime);

                   } catch (Exception ex) {

                       ex.printStackTrace();

                   } finally {

                       metadataRetriever.release();

                   }

               }

           }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());

           observable.subscribe(new Observer<Long>() {

               @Override

               public void onSubscribe(Disposable d) {

               }

               @Override

               public void onNext(Long time) {

                   Log.d("--time--",time.toString());

                   jzvdStd.totalTimeTextView.setText(JZUtils.stringForTime(time));

               }

               @Override

               public void onError(Throwable e) {

               }

               @Override

               public void onComplete() {

               }

           });

       }

    4.MainActivity的完整代码如下:

    package com.example.videotimedemo;

    import android.annotation.SuppressLint;

    import android.media.MediaMetadataRetriever;

    import android.os.Bundle;

    import android.os.Handler;

    import android.util.Log;

    import androidx.appcompat.app.AppCompatActivity;

    import com.example.videotimedemo.app.App;

    import com.example.videotimedemo.util.VideoUtils;

    import java.util.HashMap;

    import cn.jzvd.JZMediaSystem;

    import cn.jzvd.JZUtils;

    import cn.jzvd.Jzvd;

    import cn.jzvd.JzvdStd;

    import io.reactivex.ObservableEmitter;

    import io.reactivex.ObservableOnSubscribe;

    import io.reactivex.Observer;

    import io.reactivex.android.schedulers.AndroidSchedulers;

    import io.reactivex.disposables.Disposable;

    import io.reactivex.schedulers.Schedulers;

    public class MainActivity extends AppCompatActivity {

       public static final String videoUrl = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";

       private Handler mHandler;

       private JzvdStd jzvdStd;

       @Override

       protected void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);

           setContentView(R.layout.activity_main);

           mHandler = new Handler();

           initView();

           initData();

       }

       private void initData() {

           mHandler.postDelayed(new Runnable() {

               @Override

               public void run() {

                   long time = VideoUtils.getPlayTime(videoUrl);

                   Log.d("--time--",time+"");

                   jzvdStd.totalTimeTextView.setText(JZUtils.stringForTime(time));

               }

           },200);

          getDuration(videoUrl);

       }

       public void getDuration(String url){

           io.reactivex.Observable<Long> observable = io.reactivex.Observable.create(new ObservableOnSubscribe<Long>() {

               @Override

               public void subscribe(ObservableEmitter<Long> e) throws Exception {

                   android.media.MediaMetadataRetriever metadataRetriever = new android.media.MediaMetadataRetriever();

                   try {

                       if (url != null) {

                           HashMap<String, String> headers;

                           headers = new HashMap<>();

                           headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");

                           metadataRetriever.setDataSource(url, headers);

                       } else {

                           //mmr.setDataSource(mFD, mOffset, mLength);

                       }

                       long durationTime = Long.parseLong(metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));//时长(毫秒)

                       String width = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽

                       String height = metadataRetriever.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高

                       e.onNext(durationTime);

                   } catch (Exception ex) {

                       ex.printStackTrace();

                   } finally {

                       metadataRetriever.release();

                   }

               }

           }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());

           observable.subscribe(new Observer<Long>() {

               @Override

               public void onSubscribe(Disposable d) {

               }

               @Override

               public void onNext(Long time) {

                   Log.d("--time--",time.toString());

                   jzvdStd.totalTimeTextView.setText(JZUtils.stringForTime(time));

               }

               @Override

               public void onError(Throwable e) {

               }

               @Override

               public void onComplete() {

               }

           });

       }

       private void initView() {

           jzvdStd = findViewById(R.id.videoplayer);

           if (jzvdStd != null) {

               String proxyUrl = App.getProxy(this).getProxyUrl(videoUrl);

               jzvdStd.setUp(proxyUrl, "视频默认没有播放", JzvdStd.SCREEN_NORMAL, JZMediaSystem.class);

               jzvdStd.onPrepared();

           }

       }

       @Override

       protected void onPause() {

           super.onPause();

           Jzvd.goOnPlayOnPause();

       }

       @Override

       protected void onResume() {

           super.onResume();

           Jzvd.goOnPlayOnResume();

       }

       @Override

       protected void onDestroy() {

           super.onDestroy();

           Jzvd.releaseAllVideos();

       }

    }

    5.项目运行后的日志打印如下:

    6.实现的效果图如下:

    7.源码地址如下:

    https://gitee.com/jackning_admin/videotimedemo

    相关文章

      网友评论

          本文标题:Android音视频开发之获取视频默认状态总时长

          本文链接:https://www.haomeiwen.com/subject/cvqnsrtx.html