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

📄 mediaplayback.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					playback->buffering = TRUE;

					while(size < sizeI + playback->input->GetBufferingSize() && !(playback->input->GetBufferSize() >= playback->input->GetSize())) {

						Sleep(10);
						size = playback->input->GetBufferSize();
						
						playback->bufferingProgress = (size - sizeI) * 100 / playback->input->GetBufferingSize();
					}

					playback->buffering   = FALSE;
					playback->hasToBuffer = FALSE;

					playback->decaps->UpdateForSize();

					RECT rect;

					GetClientRect(playback->hwndPlayback, &rect);
					InvalidateRect(playback->hwndPlayback, &rect, TRUE); 
	 				UpdateWindow(playback->hwndPlayback);
		
					if(playback->audioRenderer->paused)
						playback->audioRenderer->Pause();
				}
			}

startPlayingWAudio:

			frame = NULL;

			if(!playback->paused) {

				if(playback->fastForward) {

					playback->decaps->SeekNextKeyFrame(0);
				}
				else {
					if(playback->rewind) {
	
						playback->decaps->SeekPreviousKeyFrame(0);
					}
				}

				/*
				 * 同步
				 *
				 */

				if(!playback->fastForward && !playback->rewind) {

					timeDiff = playback->GetVideoTime() - playback->GetAudioTime();



					if(timeDiff == 0) {
					
						/*
						 * 什么也不做
						 */
					}
					else {

						if(timeDiff > 10) {
							Sleep(timeDiff/2);
						}

						if(timeDiff < -150) {
					
							/*
							 * 跳过,不进行补偿
							 */	
					
							playback->videoBuffer->DropOneFrame();
							playback->videoFrames++;
						}


						if(timeDiff < -230) {
						
							/*
							 * 跳过,不进行补偿
							 */	
							
							playback->videoBuffer->DropOneFrame();
							playback->videoFrames++;
						}
					}
				}
				else {

					Sleep(120);
				}

				frame = playback->videoBuffer->GetOneFrame();
				playback->videoFrames++;

				if(frame == NULL) {

					/*
					 * 在文件或缓冲末尾
					 */

					if(playback->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {

						if(playback->input->GetBufferSize() < playback->input->GetSize()) {

							goto startBufferingWAudio;
						}
						else {

							if(!playback->audioRenderer->paused)
								playback->audioRenderer->Pause();

							playback->decaps->UpdateForSize();

							frame = playback->videoBuffer->GetOneFrame();

							if(playback->audioRenderer->paused)
								playback->audioRenderer->Pause();
						}
					}
				}

				if(frame == NULL) {

					if(!playback->loop) {
						
						SendMessage(playback->hwndPlayback, WM_PLAYA_PLAYBACK_END, 0, 0);
						playback->Stop(TRUE);
					}
					else {

						playback->decaps->Rewind(0, 0);
						
						if(!playback->fastForward && !playback->rewind) {
		
							if(playback->hasAudio)
								playback->audioRenderer->Stop();
	
							if(playback->hasAudio)
								playback->audioDecoder->EmptyAudioBuffer();
						}

						playback->audioBytes      = 0;
						playback->videoFrames     = 0;
						
						playback->videoBuffer->StopBuffering();
						playback->videoBuffer->StartBuffering(playback->decaps->GetVideoWidth(0));
					
						if(!playback->fastForward && !playback->rewind) {

							if(playback->hasAudio)
								playback->audioRenderer->Start();
						}
						
						goto startPlayingWAudio;
					}

					break;
				}

				WaitForSingleObject(playback->playbackMutex, INFINITE);

				if(!playback->paused) {
					
					if(playback->fullscreen) {
						
						playback->videoRenderer->DrawFullscreen(frame, playback->decaps->GetCurrentVideoFrame(0), playback->videoDecoder->GetInvertFlag(), playback->desktopMode);
					}
					else {
						
						playback->videoRenderer->Draw(frame, playback->videoRect, playback->decaps->GetCurrentVideoFrame(0), playback->videoDecoder->GetInvertFlag());
					}
				}

				ReleaseMutex(playback->playbackMutex);
			}
		}
	}

	return 0;
}

/*
 * 图形设备接口(GDI)方法
 *
 */

MP_RESULT     MediaPlayback::FlipToGDI() 
{
	return MP_RESULT_OK;
}


/**************************************************************
 *                                                            *
 *                      视频回调方法                          *
 *                 ------------------------                   *
 *                                                            *
 **************************************************************/


MP_RESULT     MediaPlayback::Play()
{
	if(this->HasAudio() || this->HasVideo()) {

		if(this->fastForward) {
	
			this->fastForward = FALSE;

			this->baseTime = GetTickCount();

			this->videoFrames = 0;
			this->audioBytes  = 0;

			if(this->decaps) {
			
				this->decaps->ReSeekAudio(0);
			}

			if(this->hasAudio) {

				this->audioDecoder->EmptyAudioBuffer();
			
				this->audioRenderer->SetVolume(this->volume);

				this->audioRenderer->Stop();
				this->audioRenderer->Start();
			}
		}
		else {

			if(this->rewind) {
	
				this->rewind  = FALSE;

				this->baseTime = GetTickCount();

				this->videoFrames     = 0;
				this->audioBytes      = 0;

				if(this->decaps) {
				
					this->decaps->ReSeekAudio(0);
				}

				if(this->hasAudio) {

					this->audioDecoder->EmptyAudioBuffer();
			
					this->audioRenderer->SetVolume(this->volume);
					this->audioRenderer->Stop();
					this->audioRenderer->Start();
				}
			}
			else {

				if(this->paused) {

					this->Pause();
					return MP_RESULT_OK;
				}

				if(this->playing)
					return MP_RESULT_ERROR;

				this->playing = TRUE;
				this->paused  = FALSE;

				this->videoFrames = 0;
				this->audioBytes  = 0;

				this->decaps->Rewind(0, 0);

				if(this->HasAudio()) {
			
					this->audioDecoder->EmptyAudioBuffer();

					this->audioRenderer->SetVolume(this->volume);

					this->videoBuffer->StartBuffering(this->decaps->GetVideoWidth(0));

					if(this->audioRenderer->paused && (this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE)) {

						this->audioRenderer->Pause();
						this->audioRenderer->Stop();
						this->audioRenderer->Start();
					}
					else {
						this->audioRenderer->Start();
					}

					this->videoThread = CreateThread( NULL, 0, PlaybackVideoAndAudioThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
		
					return MP_RESULT_OK;
				}
				else {
				
					if(this->HasVideo()) {

						this->videoBuffer->StartBuffering(this->decaps->GetVideoWidth(0));
	
						this->videoThread = CreateThread( NULL, 0, PlaybackVideoOnlyThreadFunc, (LPVOID) this, 0, &this->videoThreadId );

						return MP_RESULT_OK;
					}
				}
			}
		}
	}

	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::Pause()
{
	if(this->playing) {

		if(this->paused) {

			if(this->hasAudio) {
				this->audioRenderer->Pause();
			}

			this->paused = FALSE;

			ReleaseMutex(this->playbackMutex);

			this->baseTime += (GetTickCount() - this->stopTime);

			ResumeThread(this->videoThread);
		}
		else {
		
			WaitForSingleObject(this->playbackMutex, INFINITE);

			if(!this->fastForward && !this->rewind) {
				
				if(this->hasAudio) {
					this->audioRenderer->Pause();
				}
			}
			else {
				
				this->videoFrames     = 0;

				if(this->hasAudio) {
					
					this->decaps->ReSeekAudio(0);
					this->audioDecoder->EmptyAudioBuffer();
				
					this->audioBytes     = 0;

					this->audioRenderer->Stop();
					this->audioRenderer->Start();
					this->audioRenderer->Pause();
				}
			}

			this->fastForward = FALSE;
			this->rewind      = FALSE;

			this->stopTime = GetTickCount();

			SuspendThread(this->videoThread);
			this->paused = TRUE;
		}
	}

	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::NextFrame()
{
	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::Stop(int redrawWindow)
{
	if(this->paused)
		this->Pause();

	if(this->playing) {

		WaitForSingleObject(this->playbackMutex, INFINITE);	
		
		if(this->hasAudio) {

			this->audioRenderer->Stop();
		}

		this->playing = FALSE;

		this->buffering = FALSE;
		this->bufferingProgress = 0;

		if(this->HasVideo()) {

			this->videoBuffer->StopBuffering();
		}

		ReleaseMutex(this->playbackMutex);
	}

	this->fastForward  = FALSE;
	this->rewind       = FALSE;

	this->playing      = FALSE;
	this->paused       = FALSE;

	this->audioBytes      = 0;
	this->videoFrames     = 0;

	this->decaps->Rewind(0, 0);

	if(this->hasAudio)
		this->audioDecoder->EmptyAudioBuffer();

	if(this->videoRenderer)
		this->videoRenderer->Stop();

	/*
	 * 刷新
	 */

	RECT rect;

	if(redrawWindow) {
		
		GetClientRect(this->hwndPlayback, &rect);
		InvalidateRect(this->hwndPlayback, &rect, TRUE); 
	 	UpdateWindow(this->hwndPlayback);
	}

	TerminateThread(this->videoThread, 0);

	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::FastForward()
{
	if(this->paused) {

		this->fastForward = TRUE;
		this->paused      = FALSE;

		ReleaseMutex(this->playbackMutex);
		this->baseTime += (GetTickCount() - this->stopTime);

		ResumeThread(this->videoThread);

		return MP_RESULT_OK;
	}

	if(this->playing && !this->rewind && !this->fastForward) {

		if(this->hasAudio) {
			this->audioRenderer->Stop();
		}

		this->stopTime = GetTickCount();

		this->fastForward = TRUE;
	}

	return MP_RESULT_OK;	
}

MP_RESULT     MediaPlayback::Rewind()
{
	if(this->paused) {

		this->rewind = TRUE;
		this->paused = FALSE;

		ReleaseMutex(this->playbackMutex);
		this->baseTime += (GetTickCount() - this->stopTime);

		ResumeThread(this->videoThread);

		return MP_RESULT_OK;
	}

	if(this->playing && !this->fastForward && !this->rewind) {

		if(this->hasAudio) {
			this->audioRenderer->Stop();
		}

		this->stopTime = GetTickCount();

		this->rewind = TRUE;
	}


	return MP_RESULT_OK;	
}

MP_RESULT     MediaPlayback::MaintainImage()
{
	if(this->HasVideo()) {

		if(this->fullscreen) {

			this->videoRenderer->DrawFullscreen(this->videoBuffer->GetLastFrame(), 0, this->videoDecoder->GetInvertFlag(), this->desktopMode);
		}
		else {
			
			this->videoRenderer->Draw(this->videoBuffer->GetLastFrame(), this->videoRect, 0, this->videoDecoder->GetInvertFlag());
		}
	}

	return MP_RESULT_OK;
}

MP_RESULT     MediaPlayback::Seek(int percent)
{
	int has_to_play = 0;
	RECT rect;
	
	if(this->HasAudio() || this->HasVideo()) {
	
		if(this->playing) {

			Stop(FALSE);
			has_to_play = 1;
		}

		this->decaps->Seek(0, 0, percent);

		if(this->input->GetCaps() & MEDIA_CAPS_BUFFERIZE) {

			this->decaps->UpdateForSize();
		}

		if(this->hasAudio)
			this->audioDecoder->EmptyAudioBuffer();

		if(has_to_play) {
	
			this->playing = TRUE;
			this->paused  = FALSE;

			this->videoFrames     = 0;
			this->audioBytes      = 0;

			if(this->HasAudio()) {
			
				this->audioRenderer->Start();

				this->videoThread = CreateThread( NULL, 0, PlaybackVideoAndAudioThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
			}
			else {
				
				this->videoThread = CreateThread( NULL, 0, PlaybackVideoOnlyThreadFunc, (LPVOID) this, 0, &this->videoThreadId );
			}
		}

		GetClientRect(this->hwndPlayback, &rect);
		InvalidateRect(this->hwndPlayback, &rect, TRUE); 
	 	UpdateWindow(this->hwndPlayback);

	}
	
	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::SetFullscreen(int active, HWND hwnd)
{
	if(active && !this->fullscreen) {

		int has_to_play = 0;

		if(this->playing && !this->paused) {
			
			this->Pause();
			has_to_play = 1;
		}
		
		this->fullscreen = TRUE;

		if(this->videoRenderer->InitFullscreen(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0)) != MP_RESULT_OK) {
		
			this->videoRenderer->Init(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0));
			this->fullscreen = FALSE;

			return MP_RESULT_ERROR;
		}
			
		if(has_to_play) {

			this->Pause();
		}
	}
	else {
	
	if(this->fullscreen) {
	
			int has_to_play = 0;

			if(this->playing && !this->paused) {
			
				this->Pause();
				has_to_play = 1;
			}

			this->videoRenderer->Init(hwnd, this->decaps->GetVideoWidth(0), this->decaps->GetVideoHeight(0));
			this->fullscreen = FALSE;
		
			if(has_to_play) {

				this->Pause();
			}
		}
	}
	
	return MP_RESULT_ERROR;	
}

MP_RESULT     MediaPlayback::SetVolume(int volume)
{
	this->volume = volume;

	if(this->hasAudio) {

		this->audioRenderer->SetVolume(this->volume);
	}

	return MP_RESULT_OK;	
}

MP_RESULT     MediaPlayback::SetLoop(int loop)
{
	this->loop = loop;

	return MP_RESULT_OK;	
}

MP_RESULT     MediaPlayback::SetDesktopMode(BOOL on)
{
	this->desktopMode = on;

	return MP_RESULT_OK;
}

MP_RESULT     MediaPlayback::SetVideoRect(RECT *rect)
{
	this->videoRect = rect;

	return MP_RESULT_OK;
}

MP_RESULT     MediaPlayback::Close()
{
	if(this->input)
		this->input->Close();

	if(this->HasVideo()) {

		/*
		 * 清除视频
		 *
		 */

		this->Stop(FALSE);

		this->videoRenderer->Close();

		this->videoBuffer->StopBuffering();

		this->videoBuffer->ReleaseConnections();
		this->videoDecoder->ReleaseConnections();
		this->decaps->ReleaseConnections();

	}

	if(this->HasAudio()) {

		/*
		 * 清除音频
		 *
		 */

		this->audioRenderer->Close();
		this->audioDecoder->ReleaseConnections();
	}

	if(this->hasSubtitles) {

		this->subtitler->ReleaseConnections();
		this->subtitler->Close();
	}

	return MP_RESULT_OK;	
}

⌨️ 快捷键说明

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