GStreamer如何获取播放的duration和当前的播放position?

本文详细介绍了GStreamer中seek操作的相关知识点,包括获取播放时长和位置的方法,以及如何计算basetime来确保seek操作的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于gstreamer在seek时总会出现崩溃或其他bug,这里把与seek相关的点做一下笔记

www.cnblogs.com/super119/archive/2011/01/03/1924441.html

1. 获取duration的话,有几个途径:

(1)在bus上监听GST_MESSAGE_DURATION,如果有这个消息到来,用gst_message_parse_duration就可以获得。但是往往element不会发这样的message出来

(2)用gst_query_new_duration新建一个duration query,然后用gst_element_query(pipeline, query)查询即可。这种方法较为常用。一般可以在pipeline所有element都link好了,pipeline状态是RUNNING的时候,就可以查询了。 

2. 获取当前播放的position,也有几种办法:

(1)如果pipeline中element支持GST_QUERY_POSITION,那么可以进行查询得到。一般来说都是sink element提供position查询,因为数据从src开始,一路经过demux,decode,这中间都需要消耗时间,所以如果是非sink element提供position的话,那是不准的。

(2)如果不能query,那我现在的做法是:在sink element上add event和buffer probe。在event probe中监听NEWSEGMENT event,一般刚开始播放的话,NEWSEGMENT中的start都是0。收到该event做一些相应的动作;然后在buffer probe中将第一个buffer的timestamp记录下来,然后针对后续的buffer,就可以和第一个buffer的timestamp做减法,得到差值除以duration,就是当前的position。注意如果播放中途收到NEWSEGMENT event,那么,第一个buffer的timestamp要重新进行计算,然后最后计算position的时候记得加上NEWSEGMENT中的start,再去除以duration,这才正确。

问题2

GStreamer pipeline的basetime是如何计算出来的?

GstPipeline在从PAUSED转成PLAYING的时候,会select一个clock并计算出basetime,这两样东西都会赋给pipeline中每个element。那这个basetime每次是怎么计算的呢? 

原来认为这个basetime就是当前的clock time,但是后来发现不对。比如:在播放了2秒的时候PAUSE,等了3秒后再PLAY,此时如果这个basetime是当前时间的话,那就是5秒时刻,此时继续播放的话,会发现传过来的buffer中的timestamp是从第3秒开始的,不是从0秒开始的,因为上次暂停的时候是在2秒的时间点上。所以如果此时basetime是5秒的话,那么sink组件就要到8秒以后再播放这些buffer(因为buffer的timestamp是从3秒开始的)。 

于是回到gst_pipeline_change_state函数研究,发现其实很简单: 

base_time = start_time - stream_time + delay; 

start_time就是当前clock的时间,stream_time就是已经播放的时间(注意和running_time不一样,running_time是变成PLAYING状态后流逝的时间,而stream_time是变成PLAYING状态后sink实际播放的时间,所以stream_time一般就直接用在POSITION的QUERY上,作为POSITION直接返回的(当然,这里还有一些逻辑,不是直接返回stream time的,详情参考gst_base_sink_get_position函数)),delay是GstPipeline的一个property,可以设置的。 

这样一来就对了,还是上面的例子,先播了2秒,所以stream_time是2秒,等了3秒,到第5秒的时候play,所以start_time是5,这样算下来base_time就是3秒(如果delay设置是0的话,默认值就是0),所以接下来的buffer timestamp是3秒开始的,这样就正好接上播放了。 

如果是第一次播放,之前没有PAUSE过,那么上面的公式很清楚,此时basetime就正好是start time了。

### 回答1: 这个警告是由gstreamer引擎发出的,意思是无法查询视频的位置信息,状态码为,值为-1,时长为-1。可能是由于视频文件格式不支持或者视频文件本身出现了问题导致的。建议检查视频文件的格式完整性,或者尝试使用其他视频播放器来播放该视频文件。 ### 回答2: gstreamer是一个常用的开源多媒体框架,用于处理音视频等多种多媒体流。当我们使用gstreamer播放视频时,可能会遇到“gstreamer warning: cannot query video position: status=0, value=-1, duration=-1”的问题。 这个警告通常是由于gstreamer无法查询视频播放当前位置、状态、播放持续时间等信息而引起的。这可能是因为视频的编码方式不受支持,或者文件本身存在错误。 为了解决这个问题,我们可以尝试以下几种方法: 1. 检查视频编码方式是否受支持:如果所使用的编码方式不受gstreamer支持,那么我们就需要安装相应的插件或者转换视频格式。 2. 检查文件是否存在错误:我们可以使用命令行工具检查视频文件的格式以及文件是否存在错误。例如,使用ffmpeg命令来解码编码视频,以确保文件没有被损坏。 3. 更新gstreamer版本:如果以上两种方法都无法解决问题,我们可以尝试更新gstreamer版本。新版本可能会修复已知的问题或提供其他解决方案。 总之,当我们遇到“gstreamer warning: cannot query video position: status=0, value=-1, duration=-1”的问题时,我们应该首先检查视频编码方式文件是否存在错误,并尝试更新gstreamer版本。 如果问题仍然存在,建议咨询gstreamer社区的技术支持人员以获取更好的解决方案。 ### 回答3: 这个警告是GStreamer媒体框架的一种提示,主要提示视频的位置查询失败。其中status=0是指操作成功,而value=-1duration=-1分别表示当前无法获取视频的播放位置时长信息。 造成这个提示的原因可能有很多,比如媒体文件本身存在问题,或者GStreamer框架出现了某些异常。如果是媒体文件的问题,可能是因为该文件的格式不受GStreamer支持,或者是文件损坏导致的。如果是框架出现了异常,那么可能是代码有误或者调用了不正确的API导致的。 解决这个问题的方法也有多种途径。如果是媒体文件的问题,我们需要检查文件的格式是否存在损坏情况,可以通过某些专业的视频处理软件进行修复,以确保GStreamer框架能够正常处理该文件。如果是框架的问题,则需要检查代码是否存在错误,并且确认是否使用了正确的API。 总之,该警告可能发生的原因比较多,需要针对具体情况进行分析。在遇到该问题时,我们需要细心排查,找出根本原因,并且采取合适的措施,以确保GStreamer框架能够正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值