C# DirectShow GetDuration提供了错误的持续时间值

C# DirectShow GetDuration提供了错误的持续时间值,c#,.net,directshow,directshow.net,directsound,C#,.net,Directshow,Directshow.net,Directsound,我正在尝试使用DirectShow获取媒体文件的持续时间。我使用以下代码(C#): 以秒为单位获取媒体文件持续时间。但是,当我尝试打开3-4分钟的MP3文件时,track.Duration变为11-12分钟。我尝试了多个文件,效果总是一样的。原因可能是什么?来自: 根据源格式,持续时间可能不准确。例如,如果源包含可变比特率(VBR)流,则该方法可能返回估计的持续时间 您正在使用VBR流吗?来自: 根据源格式,持续时间可能不准确。例如,如果源包含可变比特率(VBR)流,则该方法可能返回估计的持续时

我正在尝试使用DirectShow获取媒体文件的持续时间。我使用以下代码(C#):

以秒为单位获取媒体文件持续时间。但是,当我尝试打开3-4分钟的MP3文件时,track.Duration变为11-12分钟。我尝试了多个文件,效果总是一样的。原因可能是什么?

来自:

根据源格式,持续时间可能不准确。例如,如果源包含可变比特率(VBR)流,则该方法可能返回估计的持续时间

您正在使用VBR流吗?

来自:

根据源格式,持续时间可能不准确。例如,如果源包含可变比特率(VBR)流,则该方法可能返回估计的持续时间


您是否正在使用VBR流?

您通常从应用程序端使用
IMediposition
接口(而不是
IMediseek
)。持续时间始终以秒为单位报告。不过,这不太可能有什么不同,可能的原因是使用Windows Media API从ID3标记中读取持续时间

是否有更可靠的方法使用DirectShow API获取媒体文件的确切持续时间


Windows媒体播放器通过MediaFoundation播放MP3文件,这是一个非DirectShow API,因此这里没有选择从DirectShow中期待或做完全相同的选项。

< P>您通常从应用端使用<代码> IdIpApPosie接口(而不是<代码> IdiediaseKEng/<代码>)。持续时间始终以秒为单位报告。不过,这不太可能有什么不同,可能的原因是使用Windows Media API从ID3标记中读取持续时间

是否有更可靠的方法使用DirectShow API获取媒体文件的确切持续时间


Windows媒体播放器通过MediaFoundation播放MP3文件,这是一个非DirectShow API,所以这里没有选择从DirectShow期待或做完全相同的事情。

< P>你可以在干净的Windows安装上尝试同样的方法。您可能安装了有bug的编解码器(包)。

您可以在干净的windows安装上尝试同样的方法。您可能安装了有bug的编解码器(包)。

您好,不是,它是固定比特率的MP3文件;所以,据我所知,文档从未承诺持续时间是正确的,但Windows Media Player如何知道持续时间?有没有更可靠的方法可以通过DirectShow API获得媒体文件的确切持续时间?@VASoftOnline:Hmm。。。我不知道在那种情况下。我真的希望它是好的,如果它是固定速率的…嗨,不,它是固定比特率的MP3文件;所以,据我所知,文档从未承诺持续时间是正确的,但Windows Media Player如何知道持续时间?有没有更可靠的方法可以通过DirectShow API获得媒体文件的确切持续时间?@VASoftOnline:Hmm。。。我不知道在那种情况下。如果是固定利率的话,我真的希望一切都会好起来……你改变了我的位置和我的眼神。上的文档指出“应用程序应该使用IMediseek而不是IMediposition”。我认为这不是一个好建议。在图形端,两个接口都可用,
imediposition
显然更易于使用,更不用说它是从
IDispatch
派生出来的。答案如上所述,你颠倒了我的位置和我的眼神。上的文档指出“应用程序应该使用IMediseek而不是IMediposition”。我认为这不是一个好建议。在图形端,两个接口都可用,
imediposition
显然更易于使用,更不用说它是从
IDispatch
派生出来的。因此答案如上所述。带有vbr且没有正确的xing头的Mp3文件可能计算不正确。更多信息:带有vbr和不带正确标题的Mp3文件可能计算不正确。更多信息:
var seekingParser = filter as IMediaSeeking;
if (seekingParser != null)
{
   long duration;
   if (seekingParser.SetTimeFormat(TimeFormat.MediaTime) == 0
       && seekingParser.GetDuration(out duration) == 0)
       track.Duration = duration / 10000000f;
}