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

前言:

​ 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);
}

本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

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.实现的效果图如下:

 

 本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/126249940