You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过YouTube Player API获取视频精确总观看时长(秒)

如何通过Android YouTube Player API获取视频总观看时长

嘿,我来帮你搞定这个问题!首先得明确一点:Android YouTube Player SDK本身没有直接提供在视频加载前获取总时长的方法,不过我们有两种可行的思路来实现这个需求,下面给你详细拆解:

方法一:利用YouTube Player内置方法获取(播放时获取)

YouTubePlayer实例提供了getDuration()方法,它会返回视频的总时长(单位:毫秒),但注意这个方法只有在视频加载完成、开始播放或缓冲时才会返回有效值(未加载时返回0)。

你可以在现有的回调逻辑里添加获取代码,比如修改你的PlaybackEventListener或者PlayerStateChangeListener:

修改后的PlaybackEventListener示例:

private PlaybackEventListener playbackEventListener = new PlaybackEventListener() {
    @Override
    public void onBuffering(boolean arg0) {
        Log.d("Youtube", "onBuffering");
        // 缓冲时尝试获取时长
        getVideoDuration();
    }

    @Override
    public void onPaused() {
        Log.d("Youtube", "onPaused");
    }

    @Override
    public void onPlaying() {
        Log.d("Youtube", "onPlaying");
        // 播放开始时获取时长
        getVideoDuration();
    }

    @Override
    public void onSeekTo(int arg0) { }

    @Override
    public void onStopped() { }
};

// 新增统一处理时长获取的方法
private void getVideoDuration() {
    if (youtubePlayer != null) {
        long durationMillis = youtubePlayer.getDuration();
        if (durationMillis > 0) {
            // 转换为时分秒格式
            long totalSeconds = durationMillis / 1000;
            long hours = totalSeconds / 3600;
            long minutes = (totalSeconds % 3600) / 60;
            long seconds = totalSeconds % 60;
            Log.d("Youtube", "视频总时长: " + String.format("%02d:%02d:%02d", hours, minutes, seconds));
            // 这里可以把时长保存到变量或更新UI
        }
    }
}

你也可以在PlayerStateChangeListener的onVideoStarted()或onLoaded()回调里调用getVideoDuration(),确保视频已经完成加载。

方法二:使用YouTube Data API提前获取(无需等待播放)

如果你需要在视频开始播放前就拿到时长(比如页面加载时就显示),可以调用YouTube Data API的videos.list接口,通过视频ID获取视频元数据(包含时长)。

实现步骤:

  1. 确保你的API密钥(代码里的DEVELOPER_KEY)已经在Google Cloud控制台开启了YouTube Data API权限。
  2. 发送HTTP GET请求到指定接口,解析返回的JSON数据提取时长。

示例代码(用OkHttp实现):

// 先添加OkHttp依赖(如果未引入)
// implementation 'com.squareup.okhttp3:okhttp:4.11.0'

private void fetchVideoDurationWithDataApi(String videoId) {
    OkHttpClient client = new OkHttpClient();
    String url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=" + videoId + "&key=" + com.chalklit.classes.Config.DEVELOPER_KEY;

    Request request = new Request.Builder().url(url).build();
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
            // 处理请求失败逻辑
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful() && response.body() != null) {
                String json = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(json);
                    JSONArray items = jsonObject.getJSONArray("items");
                    if (items.length() > 0) {
                        JSONObject item = items.getJSONObject(0);
                        JSONObject contentDetails = item.getJSONObject("contentDetails");
                        String durationStr = contentDetails.getString("duration");
                        // 把ISO 8601格式的时长转换为秒数
                        long durationSeconds = parseIso8601Duration(durationStr);
                        Log.d("Youtube", "视频总时长(秒): " + durationSeconds);
                        // 回到主线程更新UI
                        runOnUiThread(() -> {
                            // 在这里更新UI展示时长
                        });
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    });
}

// 解析ISO 8601时长格式的工具方法
private long parseIso8601Duration(String duration) {
    // 示例:PT1H2M3S -> 3723秒
    Pattern pattern = Pattern.compile("PT(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?");
    Matcher matcher = pattern.matcher(duration);
    long seconds = 0;
    if (matcher.find()) {
        if (matcher.group(1) != null) {
            seconds += Long.parseLong(matcher.group(1)) * 3600;
        }
        if (matcher.group(2) != null) {
            seconds += Long.parseLong(matcher.group(2)) * 60;
        }
        if (matcher.group(3) != null) {
            seconds += Long.parseLong(matcher.group(3));
        }
    }
    return seconds;
}

你可以在onCreate或onResume方法里调用这个接口,提前获取视频时长。

两种方法对比

方法优点缺点
Player内置方法无需额外网络请求,实现简单必须等视频加载/播放后才能获取,无法提前显示
YouTube Data API可以提前获取时长,支持更多元数据需要网络请求,API有调用配额限制,需配置权限

根据你的实际需求选择合适的方法就好啦!

内容的提问来源于stack exchange,提问作者Shubham Chauhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:23:46