从Android应用程序中的URL获取视频时长

问题描述 投票:0回答:4

我正在开发一个应用程序,用户可以在其中查看存储在服务器上的所有视频信息和标题。我几乎已经完成了,除了无论我如何编码,我都无法从给定的 URL 获取视频持续时间。 让我们从互联网上的某个地方获取此演示视频:单击此处获取视频路径 我希望应用程序无需打开视频本身即可获取视频时长。

我尝试在 Android 上使用的代码是这样的:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource("https://12-lvl3-pdl.vimeocdn.com/01/1386/0/6932347/10573836.mp4?expires=1461047937&token=037972137fdfc4c2d9902");
    String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
    long timeInmillisec = Long.parseLong( time );
    long duration = timeInmillisec / 1000;
    long hours = duration / 3600;
    long minutes = (duration - hours * 3600) / 60;
    long seconds = duration - (hours * 3600 + minutes * 60);
    Toast.makeText(context,Long.toString(timeInmillisec),Toast.LENGTH_SHORT).show();

但我得到的结果是:java.lang.IllegalArgumentException 在第 2 行,即“retrieve.setDataSource()”。 谁能帮助我找到我做错了什么或者android是否提供了另一种方式来获取所需的信息?

android android-video-player
4个回答
13
投票

也许您正在寻找 FFmpegMediaMetadataRetriever

FFmpegMediaMetadataRetriever类提供了一个统一的接口,用于从输入媒体文件中检索帧和元数据。

通过使用 FFmpegMediaMetadataRetrieverMETADATA_KEY_DURATION 常量,您可以获取视频的持续时间。它将返回字符串给您,然后您可以将其转换为 LONG 以获得 TIME。

这是您应该使用的代码:

FFmpegMediaMetadataRetriever mFFmpegMediaMetadataRetriever = new MediaMetadataRetriever();
mFFmpegMediaMetadataRetriever .setDataSource("Your video url");
String mVideoDuration =  mFFmpegMediaMetadataRetriever .extractMetadata(FFmpegMediaMetadataRetriever .METADATA_KEY_DURATION);
long mTimeInMilliseconds= Long.parseLong(mVideoDuration);

如果以上仍然不起作用,请使用

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
 retriever.setDataSource("Your video url", new HashMap<String, String>());
else
 retriever.setDataSource("Your video url");

来自您的代码。

希望对您有帮助。祝你好运。


12
投票

这对我有用,(如果您的应用程序变慢,请在后台线程中使用此代码)

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
  retriever.setDataSource("YourVideofileUrl", new HashMap<String, String>());
  String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
  long timeInMillisec = Long.parseLong(time);
  retriever.release();
  String duration=convertMillieToHMmSs(timeInMillisec); //use this duration

 public static String convertMillieToHMmSs(long millie) {
    long seconds = (millie / 1000);
    long second = seconds % 60;
    long minute = (seconds / 60) % 60;
    long hour = (seconds / (60 * 60)) % 24;

    String result = "";
    if (hour > 0) {
        return String.format("%02d:%02d:%02d", hour, minute, second);
    }
    else {
        return String.format("%02d:%02d" , minute, second);
    }

}

如果速度慢,请使用 AsyncTask 或协程在后台执行

 AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(model.getLink(), new HashMap<String, String>());
            String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            long timeInMillisec = Long.parseLong(time);
            retriever.release();
            String durations=convertMillieToHMmSs(timeInMillisec); //use this duration
            Log.d("durationns",durations);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    duration.setText(durations);//set in textview
                }
            });
        }
    });

1
投票

我厌倦了 MediaMetadataRetriever 和 FFmpegMediaMetadataRetriever 来检索 hls 视频的持续时间,但两者根本不起作用。 创建 ExoPlayer 并从中获取持续时间。方法如下:

suspend fun getVideoDuration(context: Context, hls: String): String {
    try {
        val timeInMillis = suspendCoroutine<Long> { coroutine ->
            ExoPlayer.Builder(context).build().also {
                it.setMediaItem(MediaItem.fromUri(hls))
                it.prepare()
                it.addListener(object : Player.Listener {
                    override fun onPlaybackStateChanged(playbackState: Int) {
                        if (playbackState == Player.STATE_READY) {
                            val timeInMillis: Long = it.duration
                            it.removeListener(this)
                            it.release()
                            coroutine.resume(timeInMillis)
                        }
                    }
                })
            }
        }
        return convertMillieToHhMmSs(timeInMillis)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return "00:00:00"
}

这里我使用 suspendCoroutine 来挂起该函数,直到侦听器触发。

这是转换函数

fun convertMillieToHhMmSs(millis: Long): String {
    val seconds = millis / 1000
    val second = seconds % 60
    val minute = seconds / 60 % 60
    val hour = seconds / (60 * 60) % 24
    return if (hour > 0) {
        String.format("%02d:%02d:%02d", hour, minute, second)
    } else {
        String.format("%02d:%02d", minute, second)
    }
}

您应该从协程中调用此函数,以下是如何从片段中调用此函数:

    viewLifecycleOwner.lifecycleScope.launch { 
        getVideoDurationZ(requireContext(), "https://link/video....m3u8")
    }

0
投票

获取音频和视频的持续时间::

fun getMediaDuration(mContext: Context, uri: String): String {
    val uri = Uri.parse(uri)
    var minutes = ""
    var seconds = ""

    MediaPlayer.create(mContext, uri).also {
        val millis = it.duration.toLong()
        minutes = TimeUnit.MILLISECONDS.toMinutes(millis).toString()
        seconds = TimeUnit.MILLISECONDS.toSeconds(millis).toString()

        it.reset()
        it.release()
    }

    return "$minutes:$seconds"
}
© www.soinside.com 2019 - 2024. All rights reserved.