我正在开发适用于Windows 8.1和wp 8.1的通用应用
我写了一个用于解码mp3文件的小c ++源代码,现在我想找到一种方法来获得使用media foundation api解码文件之前的总时间长度。
由于
答案 0 :(得分:1)
MS Media Foundation可以为您提供MP3文件的属性,包括持续时间。这里有一个sample app on Github,相关的代码在这里摘录。这不是我的代码,它不会使用StorageFile
给出的异步接口开箱即用,但将方形钉固定到圆孔中的工作非常简单。 / p>
请注意,此Duration
符合MF_PD_DURATION documentation on MSDN的100纳秒刻度。
#include <collection.h>
#include <ppltasks.h>
#include <mfidl.h>
#include <mfapi.h>
#include <mfreadwrite.h>
#include <wrl.h>
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")
using namespace Platform;
using namespace Windows::Storage::Streams;
using namespace Microsoft::WRL;
// Only throw in exception based code (C++/CX), never throw in HRESULT error code based code.
#define THROW_IF_FAILED(hr) { if (FAILED(hr)) throw Platform::Exception::CreateException(hr); }
#pragma comment(lib, "mfreadwrite.lib")
namespace MFUtils
{
// This WinRT object provides JavaScript or C# code access to the information in the stream
// that it needs to construct the AudioEncodingProperties needed to construct the AudioStreamDescriptor
// needed to create a MediaStreamSource. Here is how to create it
// var helper = new MFUtils.MFAttributesHelper(self.memoryStream, data.mimeType);
public ref class MFAttributesHelper sealed
{
public:
property UINT64 Duration;
property UINT32 BitRate;
property UINT32 SampleRate;
property UINT32 ChannelCount;
// The synchronous design only works with in memory streams.
MFAttributesHelper(InMemoryRandomAccessStream^ stream, String^ mimeType)
{
THROW_IF_FAILED(MFStartup(MF_VERSION));
// create an IMFByteStream from "stream"
ComPtr<IMFByteStream> byteStream;
THROW_IF_FAILED(MFCreateMFByteStreamOnStreamEx(reinterpret_cast<IUnknown*>(stream), &byteStream));
// assign mime type to the attributes on this byte stream
ComPtr<IMFAttributes> attributes;
THROW_IF_FAILED(byteStream.As(&attributes));
THROW_IF_FAILED(attributes->SetString(MF_BYTESTREAM_CONTENT_TYPE, mimeType->Data()));
// create a source reader from the byte stream
ComPtr<IMFSourceReader> sourceReader;
THROW_IF_FAILED(MFCreateSourceReaderFromByteStream(byteStream.Get(), nullptr, &sourceReader));
// get current media type
ComPtr<IMFMediaType> mediaType;
THROW_IF_FAILED(sourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediaType));
// get all the data we're looking for
PROPVARIANT prop;
THROW_IF_FAILED(sourceReader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &prop));
Duration = prop.uhVal.QuadPart;
UINT32 data;
THROW_IF_FAILED(sourceReader->GetPresentationAttribute(MF_SOURCE_READER_MEDIASOURCE, MF_PD_AUDIO_ENCODING_BITRATE, &prop));
BitRate = prop.ulVal;
THROW_IF_FAILED(mediaType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &data));
SampleRate = data;
THROW_IF_FAILED(mediaType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &data));
ChannelCount = data;
}
private:
~MFAttributesHelper()
{
MFShutdown();
}
};
}