Android ExoPlayer:获取直播流的当前时间
获取ExoPlayer中RTMP直播的实际时间
嘿,这个问题我之前做直播项目的时候也碰到过——ExoPlayer的getCurrentPosition()对直播流来说,确实只会返回你开始播放后的相对时长,而不是直播内容对应的实际时间。不过别担心,只要你的RTMP流本身携带了时间戳信息,还是有办法拿到实际时间的,下面给你两种可行的方案:
方案一:通过ExoPlayer的Timeline获取直播时间
ExoPlayer的Timeline对象会存储直播流的关键时间信息,我们可以通过监听时间线变化来提取实际直播时间:
- 给Player注册一个
Listener,监听时间线变更事件 - 在回调中获取当前直播窗口的
presentationStartTimeMs(这是直播流的起始UTC时间戳,单位毫秒) - 用这个起始时间加上
getCurrentPosition()返回的相对时长,就能得到当前直播内容的实际时间
player.addListener(new Player.Listener() { @Override public void onTimelineChanged(Timeline timeline, int reason) { super.onTimelineChanged(timeline, reason); Window currentWindow = new Window(); // 获取当前播放窗口的信息 timeline.getWindow(player.getCurrentWindowIndex(), currentWindow); if (currentWindow.isLive()) { long presentationStartTimeMs = currentWindow.getPresentationStartTimeMs(); // 检查服务器是否提供了有效起始时间 if (presentationStartTimeMs != C.TIME_UNSET) { // 计算实际直播时间:起始时间 + 相对播放时长 long actualLiveTimeMs = presentationStartTimeMs + player.getCurrentPosition(); // 转换成可读的日期格式 Date actualLiveTime = new Date(actualLiveTimeMs); // 这里就可以使用actualLiveTime了,比如显示给用户或者做业务逻辑处理 } } } });
注意:这个方法的前提是你的RTMP服务器已经正确传递了直播的起始时间戳,如果服务器没提供,presentationStartTimeMs会返回C.TIME_UNSET,这种情况下就没法用这个方法了
方案二:监听RTMP流的元数据获取时间
有些RTMP服务器会在流的元数据中携带当前直播的时间戳,我们可以通过ExoPlayer的MetadataOutput来监听这些元数据:
- 创建一个
MetadataOutput实例,实现onMetadata回调来解析元数据中的时间信息 - 在创建RTMP MediaSource时,将这个
MetadataOutput添加进去
// 创建元数据监听器 MetadataOutput metadataOutput = new MetadataOutput() { @Override public void onMetadata(Metadata metadata) { // 遍历所有元数据条目,查找时间相关字段 for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); // 这里以ID3格式的TIMESTAMP字段为例,不同服务器可能用不同格式 if (entry instanceof TextInformationFrame) { TextInformationFrame id3Frame = (TextInformationFrame) entry; if ("TIMESTAMP".equals(id3Frame.id)) { try { // 将元数据中的时间字符串转换成毫秒时间戳 long actualTimeMs = Long.parseLong(id3Frame.value); Date actualLiveTime = new Date(actualTimeMs); // 处理获取到的实际时间 } catch (NumberFormatException e) { e.printStackTrace(); } } } // 如果是AMF格式的元数据,需要做对应的解析逻辑 } } }; // 创建RTMP MediaSource并添加元数据监听器 RtmpMediaSource.Factory rtmpFactory = new RtmpMediaSource.Factory(); MediaItem mediaItem = MediaItem.fromUri("你的RTMP流地址"); RtmpMediaSource mediaSource = (RtmpMediaSource) rtmpFactory.createMediaSource(mediaItem); mediaSource.addMetadataOutput(metadataOutput); // 将MediaSource设置给Player player.setMediaSource(mediaSource);
注意:这个方法完全依赖于RTMP服务器的配置——只有服务器主动发送包含时间戳的元数据,客户端才能拿到。不同服务器的元数据格式可能不同,你需要和服务器开发人员确认时间字段的名称和格式
最后提醒
如果以上两种方法都没法拿到实际时间,大概率是你的RTMP服务器没有传递任何时间相关的信息。这种情况下,客户端是无法获取到直播的实际时间的,需要先调整服务器的配置,让它在流中携带时间戳信息。
内容的提问来源于stack exchange,提问作者Rohan M
相关产品推荐
相关产品推荐

