⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 player.cpp

📁 PPC流行的播放软件gsplayer源码2.24版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
BOOL CPlayer::GetStreamTitle(LPTSTR pszTitle)
{
	if (_tcslen(m_szOvdTitle)) {
		_tcscpy(pszTitle, m_szOvdTitle);
		return TRUE;
	}

	return m_Receiver.GetStreamTitle(pszTitle);
}

void CPlayer::GetOptions(MAP_OPTIONS* pOptions)
{
	*pOptions = m_Options;
}

BOOL CPlayer::SetOptions(MAP_OPTIONS* pOptions)
{
	if (m_Status != MAP_STATUS_STOP)
		return FALSE;

	if (m_Options.nOutputPrebuffer < 0 || m_Options.nOutputPrebuffer > 100)
		return FALSE;

	if (pOptions->nOutputBufferLen == m_Options.nOutputBufferLen &&
		pOptions->fAlwaysOpenDevice == m_Options.fAlwaysOpenDevice &&
		pOptions->fFadeIn == m_Options.fFadeIn) {
		m_Options = *pOptions;
		return TRUE;
	}

	m_Output.CloseAll();
	if (!m_Output.SetOutputParam(pOptions->nOutputBufferLen, 
							pOptions->fAlwaysOpenDevice, pOptions->fFadeIn))
		return FALSE;

	m_Options = *pOptions;
	return TRUE;
}

void CPlayer::GetStreamingOptions(MAP_STREAMING_OPTIONS* pOptions)
{
	pOptions->nBuf = m_Receiver.GetBufferCount();
	pOptions->nPreBuf = m_Receiver.GetPrebufferingCount();
	pOptions->fUseProxy = m_Receiver.GetProxy(pOptions->szProxy);
	m_Receiver.GetUserAgent(pOptions->szUserAgent);
}

BOOL CPlayer::SetStreamingOptions(MAP_STREAMING_OPTIONS* pOptions)
{
	if (!m_Receiver.SetBufferCount(pOptions->nBuf))
		return FALSE;

	int nPreBuf = pOptions->nPreBuf;
	if (nPreBuf > pOptions->nBuf)
		nPreBuf = pOptions->nBuf;
	m_Receiver.SetPrebufferingCount(nPreBuf);
	m_Receiver.SetProxy(pOptions->fUseProxy, pOptions->szProxy);
	m_Receiver.SetUserAgent(pOptions->szUserAgent);

	return TRUE;
}

MAP_STREAMING_STATUS CPlayer::GetStreamingStatus()
{
	return m_StreamingStatus;
}

int CPlayer::GetStreamingBufferingCount()
{
	if (m_StreamingStatus < MAP_STREAMING_CONNECTING)
		return 0;

	return m_Receiver.GetBufferingCount();
}

// protected members

void CPlayer::PostCallbackMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PostMessage(m_hwndMessage, uMsg, wParam, lParam);
}

void CPlayer::UpdateStatus(MAP_STATUS status, BOOL fError)
{
	if (m_Status != status) {
		m_Status = status;
		PostCallbackMessage(MAP_MSG_STATUS, status, fError);
	}
}

void CPlayer::UpdatePeek()
{
	PostCallbackMessage(MAP_MSG_PEEK, m_Output.m_nLPeek, m_Output.m_nRPeek);
}

BOOL CPlayer::PreparePlayback()
{
	if (m_fStop)
		return FALSE;

	CAutoLock lock(&m_csecInterface);

	int nBitsPerSample;
	switch (m_fOpen) {
	case OPEN_WAV_FILE:
		nBitsPerSample = m_pwfxDst->wBitsPerSample; break;
	case OPEN_PLUGIN:
		nBitsPerSample = m_nPlugInBps; break;
	default:
		nBitsPerSample = 16;
	}

	if (!m_Output.Open(m_Info.nChannels, m_Info.nSamplingRate, nBitsPerSample))
		return FALSE;

	m_cbOutBuf = m_Output.GetBufferSize();
	m_Output.Pause(TRUE);

	m_Decoder.Init();
	m_BassBoost.Open(m_Info.nChannels, m_Info.nSamplingRate);
	m_Echo.Open(m_Info.nChannels, m_Info.nSamplingRate);
	m_Reverb.Open(m_Info.nChannels, m_Info.nSamplingRate);

	if (m_Info.nChannels == 2)
		m_3DChorus.Open(m_Info.nSamplingRate);

	m_fPlay = TRUE;
	m_fStop = FALSE;
	SetThreadPriority(m_hThread, INITIAL_THREAD_PRIORITY);

	return TRUE;
}

BOOL CPlayer::UnpreparePlayback(BOOL fEos, BOOL fError)
{
	if (fEos) {
		if (m_pOutHdr) {
			OutputBuffer(m_pOutHdr, m_cbOutBuf - m_cbOutBufLeft);
			m_pOutHdr = NULL;
			m_cbOutBufLeft = 0;
		}
		while (!m_Output.IsFlushed()) {
			if (m_fPlay && GetStatus() == MAP_STATUS_PLAY) {
				m_Output.Pause(FALSE);
				m_fPlay = FALSE;
			}
			Sleep(1);
			if (m_fSeek)
				return FALSE;
			if (m_fStop)
				break;
			UpdatePeek();
		}
	}

	m_Output.Close();
	m_Echo.Close();
	m_Reverb.Close();
	m_BassBoost.Close();
	m_3DChorus.Close();
	m_Decoder.Destroy();

	if (!m_Options.fAlwaysOpenDevice || fError)
		m_Output.CloseAll();

	if (m_fOpen == OPEN_URL) {
		m_Receiver.Disconnect();
		m_StreamingStatus = MAP_STREAMING_DISCONNECTED;
	}

	m_pOutHdr = NULL;
	m_cbOutBufLeft = 0;

	m_nSeek = 0;
	m_fPlay = FALSE;
	m_fStop = FALSE;
	m_fSeek = FALSE;

	switch (m_fOpen) {
	case OPEN_PLUGIN:
		PlugInStop(); break;
	case OPEN_MPG_FILE:
		MpgStop(); break;
	case OPEN_OV_FILE:
		OvStop(); break;
	case OPEN_WAV_FILE:
		WavStop(); break;
	case OPEN_URL:
		NetStop(); break;
	}

	PostMessage(m_hwndMessage, MAP_MSG_PEEK, 0, 0);
	UpdateStatus(MAP_STATUS_STOP, fError);
	return TRUE;
}

void CPlayer::OutputBuffer(WAVEHDR* pHdr, DWORD cbRecorded)
{
	int nBitsPerSample;
	switch (m_fOpen) {
	case OPEN_WAV_FILE:
		nBitsPerSample = m_pwfxDst->wBitsPerSample; break;
	case OPEN_PLUGIN:
		nBitsPerSample = m_nPlugInBps; break;
	default:
		nBitsPerSample = 16;
	}

	// 愭摢偺柍壒僒儞僾儖偺彍嫀
	if (m_fOpen != OPEN_URL) {
		if (m_fFileBegin) {
			m_Output.SetFadeOff();
			if (m_Options.fSuppressZeroSamples) {
				DWORD cb = m_Output.ScanZeroSamples(TRUE, (BYTE*)pHdr->lpData, cbRecorded);
				if (cb == cbRecorded) {
					pHdr->dwBytesRecorded = 0;
					m_Output.OutputBuffer(pHdr);
					m_nSeek += cb / (m_Info.nChannels * (nBitsPerSample / 8));
#ifdef _WIN32_WCE
					Sleep(1);
#endif
					return;
				}
				else {
					cbRecorded -= cb;
					memmove(pHdr->lpData, pHdr->lpData + cb, cbRecorded);
					m_nSeek += cb / (m_Info.nChannels * (nBitsPerSample / 8));
				}
			}
			m_fFileBegin = FALSE;
		}
		else {
			// 僼傽僀儖枛旜偺柍壒偺彍嫀
			if (m_Options.fSuppressZeroSamples) {
				if (m_fSuppress) {
					pHdr->dwBytesRecorded = 0;
					m_Output.OutputBuffer(pHdr);
					return;
				}

				if (m_nWritten + m_nSeek >= m_nDuration - (m_Info.nSamplingRate * 10)) { // 枛抂10昩偵摓払偟偨偐丠
					DWORD cb = m_Output.ScanZeroSamples(FALSE, (BYTE*)pHdr->lpData, cbRecorded);
					if ((int)cb > m_Info.nChannels * m_Info.nSamplingRate * (nBitsPerSample / 8) / 100) { // 10儈儕昩埲忋柍壒偑偁傞偐丠
						cbRecorded -= cb;
						m_fSuppress = TRUE;
					}
				}
			}
		}
	}
	
	pHdr->dwBufferLength = pHdr->dwBytesRecorded = cbRecorded;

	// 僄僼僃僋僩偺張棟
	short* p = (short*)pHdr->lpData;
	if (m_Info.nChannels == 2) {
		m_3DChorus.Process(nBitsPerSample, (LPBYTE)p, cbRecorded);
		m_Surround.Process(nBitsPerSample, p, cbRecorded);
	}

	m_BassBoost.Process(nBitsPerSample, p, cbRecorded);
	m_Echo.Process(nBitsPerSample, p, cbRecorded);
	m_Reverb.Process(nBitsPerSample, p, cbRecorded);

	// 僺乕僋儊乕僞傪峏怴
	UpdatePeek();

	// 弌椡
	m_Output.OutputBuffer(pHdr);
	m_nWritten += pHdr->dwBytesRecorded / (nBitsPerSample / 8 * m_Info.nChannels);

	// 嵞惗奐巒捠抦
	if (m_fPlay && GetStatus() == MAP_STATUS_PLAY) {
		if ((int)m_Output.GetBufferingSamples() >= 
			((m_Info.nSamplingRate * m_Options.nOutputBufferLen) / 1000) * m_Options.nOutputPrebuffer / 100) {
			m_Output.Pause(FALSE);
			m_fPlay = FALSE;

			::SetThreadPriority(m_hThread, m_Options.nThreadPriority);
		}
		else if (m_Output.GetBufferingCount() == m_Output.GetBufferCount()) {
			m_Output.Pause(FALSE);
			m_fPlay = FALSE;

			::SetThreadPriority(m_hThread, m_Options.nThreadPriority);
		}
	}
}

void CPlayer::AudioDeviceClose()
{
	if (m_Status != MAP_STATUS_STOP)
		Stop();

	m_Output.CloseAll();
}

void CPlayer::GetBufferInfo(DWORD* pcbTotalAudio, DWORD* pcbBufferedAudio,
							DWORD* pcbTotalStream, DWORD* pcbBufferedStream)
{
	m_Output.GetBufferInfo(pcbTotalAudio, pcbBufferedAudio);
	m_Receiver.GetBufferInfo(pcbTotalStream, pcbBufferedStream);
}

BOOL CPlayer::WaitForPrebuffering(int nBuffering)
{
	if (!nBuffering)
		nBuffering = m_Receiver.GetPrebufferingCount();

	while (TRUE) {
		if (m_fStop)
			return FALSE;
		if (!m_Receiver.IsConnected())
			return m_Receiver.IsEos() ? TRUE : FALSE;

		if (m_Receiver.GetBufferingCount() >= nBuffering)
			return TRUE;

		Sleep(1);
	}
}

void CPlayer::Preamp(LPBYTE pbBuf, DWORD cbBuf)
{
	if (m_fPreamp)
		m_Output.Preamp(pbBuf, cbBuf, m_nPreampRate);
}

DWORD WINAPI CPlayer::PlayerThreadProc(LPVOID pParam)
{
	CPlayer* pPlayer = (CPlayer*)pParam;

	if (pPlayer->m_fOpen == OPEN_URL)
		pPlayer->NetStreamingThread();
	else
		pPlayer->FilePlayerThread();

	return 0;
}

void CPlayer::FilePlayerThread()
{
	int nRet = RET_ERROR;

	UpdateStatus(MAP_STATUS_WAIT);
	if (!PreparePlayback()) {
		UnpreparePlayback(FALSE, TRUE);
		return;
	}
	UpdateStatus(MAP_STATUS_PLAY);

retry:
	switch (m_fOpen) {
	case OPEN_PLUGIN:
		nRet = PlugInPlayerThread(); break;
	case OPEN_MPG_FILE:
		nRet = MpgPlayerThread(); break;
	case OPEN_OV_FILE:
		nRet = OvPlayerThread(); break;
	case OPEN_WAV_FILE:
		nRet = WavPlayerThread(); break;
	}

	switch (nRet) {
	case RET_EOF:
		if (!UnpreparePlayback(TRUE))
			goto retry;
		break;
	case RET_STOP:
		UnpreparePlayback();
		break;
	case RET_ERROR:
		UnpreparePlayback(FALSE, TRUE);
		break;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -