多音轨wma格式音频选择音轨问题
在大部分播放器中,包括暴风影音和千千静听等都不能对多语言音轨的wma格式音频进行音轨选择操作。windows media player可以进行音轨选择。
在使用directshow做自己的播放器时,有时会有特殊需求需要选择音轨,但又同时不能用wmplayer时,就需要自己实现音轨选择功能了。
实现方案
dshow的WMASFReader Filter提供了IWMReaderAdvanced, IWMReaderAdvanced2接口,但并未提供SetStreamsSelected等wmfsdk的用于选择音轨的接口,所以,WMASFReader 是用不了了,只能自己写过一个sourcefilter。关于sourceFilter的列子可以参考directshow实务精选里的Appendix_D/FilterQQSource。可以直接在上面改,然后在里面使用WMFormat的IWMReaderAdvanced接口来进行wma文件的读取和音轨的选择。关于使用wmformat读取文件可以参考sdk里的sample,也可参考<windows media编程向导>里的samples/Players例子,可以直接使用例子提供的一个wmreader类来进行读文件。
如有改进建议或意见,或有应用需求,请联系QQ:22154912
HRESULT CASFOutPin::FillBuffer(IMediaSample * pSample)
{
//=================================================================
if (g_pWMReader->mIsEOF)//&&g_pWMReader->m_nUsedBufferCount<1)
{
return S_FALSE;
}
// CAutoLock lock(&mSharedState);
// lock(&mSharedState);
if (m_bChangeStart)
{
Sleep(30);
// while (g_pWMReader->m_nUsedBufferCount<2)
// {
// Sleep(5);
// }
m_bChangeStart = FALSE;
}
while (g_pWMReader->m_nUsedBufferCount<1)
{
Sleep(5);
continue;
}
WriteLog("FillBuffer/n");
CheckPointer(pSample,E_POINTER);
// ASSERT(m_Ball);
BYTE *pData;
long lDataLen;
pSample->GetPointer(&pData);//得到Sample的地址指针
lDataLen = pSample->GetSize();//得到Sample的大小
ZeroMemory(pData, lDataLen);//清零
{
// CAutoLock cAutoLockShared(&m_cSharedState);
CopyMemory(pData,g_pWMReader->m_pBufferNodeFillBuffer->pBuffer, g_pWMReader->m_pBufferNodeFillBuffer->nBufferLen);
ZeroMemory(g_pWMReader->m_pSampleData,g_pWMReader->m_pBufferNodeFillBuffer->nBufferLen);
// The current time is the sample's start
CRefTime rtStart,rtSampleTime;// = m_rtSampleTime;
rtStart = g_pWMReader->m_pBufferNodeFillBuffer->nSampleTime-m_rtStart;
rtSampleTime = g_pWMReader->m_pBufferNodeFillBuffer->nSampleTime+(long)((float)lDataLen/176400*10000000);//这个数只是针对44.1kHz16bit的数值。
// Increment to find the finish time
pSample->SetActualDataLength(g_pWMReader->m_pBufferNodeFillBuffer->nBufferLen);
pSample->SetTime((REFERENCE_TIME *) &rtStart,(REFERENCE_TIME *) &rtSampleTime);//(REFERENCE_TIME *) &m_rtSampleTime);
g_pWMReader->m_pBufferNodeFillBuffer = g_pWMReader->m_pBufferNodeFillBuffer->pNext;
g_pWMReader->m_nUsedBufferCount--;
g_pWMReader->Resume();
}
//=================================================================
pSample->SetSyncPoint(TRUE);
return NOERROR;
}
HRESULT CWMReader::OnSample( /* [in] */ DWORD dwOutputNum,
/* [in] */ QWORD cnsSampleTime,
/* [in] */ QWORD cnsSampleDuration,
/* [in] */ DWORD dwFlags,
/* [in] */ INSSBuffer __RPC_FAR *pSample,
/* [in] */ void __RPC_FAR *pvContext )
{
#ifdef _DEBUG
DWORD threadId = GetCurrentThreadId();
#endif
// Check the output number of the sample against the stored output number.
// Because only the first audio output is stored, all other outputs,
// regardless of type, will be ignored.
if (dwOutputNum != mOutputNum)
{
WriteLog("dwOutputNum != mOutputNum/n");
return S_OK;
}
BYTE *pData = NULL;
DWORD cbData = 0;
// Get the sample from the buffer object.
HRESULT hr = pSample->GetBufferAndLength(&pData, &cbData);
if (FAILED(hr))
{
return hr;
}
mTimeElapsed = cnsSampleTime;
//================================================================
g_Time2=cnsSampleTime;
while (m_nUsedBufferCount>2)
{
Sleep(5);
continue;
}
if (m_pSampleData == NULL)
{
m_pSampleData = ( BYTE * )new BYTE[ BUFFERSIZE ];
}
CopyMemory(m_pBufferNodeOnSample->pBuffer, pData, cbData);
WriteLog("CopyMemory(m_pBufferNodeOnSample->pBuffer, pData, cbData);/n");
m_pBufferNodeOnSample->nBufferLen = cbData;
m_pBufferNodeOnSample->nSampleTime = cnsSampleTime;
m_pBufferNodeOnSample = m_pBufferNodeOnSample->pNext;
m_nUsedBufferCount++;
if (m_nUsedBufferCount>2)
{
Pause();
}
CopyMemory(m_pSampleData,pData,cbData);
WriteLog("CopyMemory(m_pSampleData,pData,cbData);/n");
if( FAILED( hr ) )
{
return( hr );
}
// BOOL ret = mPlayer->Play(pData, cbData, cnsSampleTime);
return(S_OK);// ret ? S_OK : E_FAIL;
//==============================================================
}
分享到:
相关推荐
多音轨切换
MX Player(可切换字幕音轨).apk
1116081994011520安卓版可切换字幕音轨电视投屏.apk
StereoscopicPlayer + ffdshow 实现外挂字幕和音轨切换 图文说明,以亲身使用绝对能用
合成双音轨的软件,做KTV歌曲用的,可以合并双声道
转码双音轨为双声道,有的设备布置吃音轨切换,但支持升到切换,次方法可完美解决
本程序可以实现midi格式音乐各个音轨的分离。每个音轨生成一个单独的文件,这样可以单独收听每个乐器的声音(也可能多个乐器一个音轨)
mts音轨提取软件,用于提取MTS视频中的音轨。
狸窝音轨合并工具是一款可以将双音轨音频文件合并成一个单音轨音频文件的工具,合并后也是一个带有左右声道的文件,主要用于卡拉ok时使用,转换后,格式也将会变成mpg或者avi格式,更加适合卡拉OK时使用,需要的朋友...
抓取CD音轨的软件,把CD音轨保存成mp3文件或者高质量音乐文件,方便传播与收听
Android音轨合成 重要的地方都加了注释
MKV视频音轨合并提取工具,可以提取或者合并mkv文件的视频或者音轨,做多语言视频的好工具。
行业分类-设备装置-媒体播放中的音轨切换方法和媒体播放设备.zip
双音轨合并
行业分类-设备装置-多媒体播放器的音轨切换方法、系统及对应播放器和设备.zip
用了就知道
在蓝光BD原盘中添加TrueHD音轨和中文字幕
AC3 DTS 音轨切割延时软件 用于改变音轨时间。
static void Main(string[] args) { String[] audioFilenames = new ... // 混合多音轨输出为 Output.wav,临时文件存储目录指向D盘根目录 WAVFile.MergeAudioFiles(audioFilenames, "Output.wav", "D:\\"); }
视频剪切 合并 工具 支持多音轨 ! 非常好用 我 自己用的软件