当前位置: 首页 > news >正文

北京网站建设laitang公司设计网页

北京网站建设laitang,公司设计网页,顺义便宜的建站公司,多种大连网站建设0#xff0c;前言 工作需要使用C制作一个ue4的视频插件#xff0c;其中一个功能是能够选择 运行时是否自动播放 视频的功能。 在实现时遇见了一个问题#xff0c;取消自动播放之后#xff0c;运行时首帧是没有取到的#xff0c;在场景里面看是黑色的。就这个问题我想到了使…0前言 工作需要使用C制作一个ue4的视频插件其中一个功能是能够选择 运行时是否自动播放 视频的功能。         在实现时遇见了一个问题取消自动播放之后运行时首帧是没有取到的在场景里面看是黑色的。就这个问题我想到了使用了一个线程去监控纹理渲染渲染到第一帧就暂停这样的效果看起来就是取消自动播放时视频插件在场景中显示视频的第一帧。插件的代码不方便贴出来我这里只贴线程监控的代码。         大部分都是使用蓝图和UE自带的mediaplayer实现视频播放的方案直接使用UE的mediaplayer他在给plane附加纹理的时候会自动生成一个当前视频帧的材质所以看不到黑帧。但是其实在打开ue第一次运行的时候还没有读取视频视频帧的材质也是黑帧。         中间尝试了在mediaplayer中添加回调在MediaOpened事件中调用play()然后调用seek()函数在SeekCompleted事件中调用pause()函数来做到播放第一帧的效果但是play()函数只是设置rate为1渲染第一帧的工作是别的线程实现的这也就导致在SeekCompleted事件中调用pause()函数时另一个线程还没有渲染第一帧从而运行时还是显示黑帧。 1原理 查看了mediaplayer的源码大概捋了一下它的流程下面是流程图分了两个线程一个向队列里面送buffer一个从队列里面取buffer之后送去渲染          这只是其中一部分和mediaplayer有关的线程中间还有很多流程。但我们只需要了解到这个线程是怎么运行的就能够解决目前的问题。         大家可以去贴出来的函数里面打个断点跟一下下流程大概了解一下就行。         主要看一下第二天取buffer的线程也就是红框中的流程有下面的代码 while (SampleQueue-Dequeue(Sample));if (!Sample.IsValid()){// Player is active (do not clear), but we have no new data// - we do not need to trigger anything on the renderthreadreturn;}UpdateSampleInfo(Sample);RenderParams.TextureSample Sample;RenderParams.Rate CurrentPlayerPtr-GetRate();RenderParams.Time Sample-GetTime();         其中最后一行代码 Sample-GetTime(); 这个GetTime()是纹理中player的时间我猜是记录播放时长我们利用这个来实现监控纹理。         原理就是获取视频的帧率从而获取每帧播放的时长启动一个线程监控纹理的player的播放时长在大于每帧播放时间的时候就暂停掉从而实现第一帧暂停的效果。 2实现 多线程的时候代码参考照抄了这位博主的 UE4 C 子线程的创建及使用_ue4 启动线程_北极熊的奋斗史的博客-CSDN博客 头文件 class RNGThread : public FRunnable { public://ConstructorRNGThread(int Count 50000, int minNumber 0, int maxNumber 1000, int chunkCount 20);//Destructor~RNGThread();// 杀死线程该线程将不能再使用想再开启的话需要重新创建//Use this method to kill the thread!!void EnsureCompletion();// 暂停线程//Pause the thread void PauseThread();// 继续线程//Continue/UnPause the threadvoid ContinueThread();// 当前线程是否处于暂停状态bool IsThreadPaused();bool setMediaPlayer(UMediaPlayer* MediaPlayer);bool setVideoComponent(UPXVideoComponent* PXVideoComponent);protected://FRunnable interface.virtual bool Init();virtual uint32 Run();virtual void Stop();private://Thread to run the worker FRunnable onFRunnableThread* Thread;UMediaPlayer* MediaPlayer nullptr;UPXVideoComponent* PXVideoComponent nullptr;FCriticalSection m_mutex; // 线程锁FEvent* m_semaphore; // 信号量int m_chunkCount;int m_amount;int m_MinInt;int m_MaxInt;//As the name states those members are Thread safeFThreadSafeBool m_Kill; // bool 类型的变量线程安全FThreadSafeBool m_Pause;}; 源文件 RNGThread::RNGThread(int Count, int minNumber, int maxNumber, int chunkCount) {m_Kill false;m_Pause false;//Initialize FEvent (as a cross platform (Confirmed Mac/Windows))m_semaphore FGenericPlatformProcess::GetSynchEventFromPool(false); // 信号量m_MinInt minNumber;m_MaxInt maxNumber;m_chunkCount chunkCount;// 启动线程Thread FRunnableThread::Create(this, TEXT(RNGThread), 0, TPri_BelowNormal); }RNGThread::~RNGThread() {if (m_semaphore){//Cleanup the FEventFGenericPlatformProcess::ReturnSynchEventToPool(m_semaphore);m_semaphore nullptr;}if (Thread){//Cleanup the worker threaddelete Thread;Thread nullptr;} }bool RNGThread::Init() {//Init the Data return true; }/***************************************************************************************/ /*注意不要在线程中做 spawning / modifying / deleting UObjects / AActors 等等之类的事 */ /***************************************************************************************/uint32 RNGThread::Run() {// 等待一下初始化//Initial wait before startingFPlatformProcess::Sleep(0.03);// 判断是否停止了线程while (!m_Kill){// 判断当前是否处于暂停状态if (m_Pause){//使用信号量使线程处于睡眠状态直到被唤醒m_semaphore-Wait();if (m_Kill){return 0;}}else{if(MediaPlayer ! nullptr){float framerate MediaPlayer-GetVideoTrackFrameRate(0,0);FTimespan FrameTime FTimespan::FromSeconds(1 / (FMath::IsNearlyZero(framerate) ? -1 : framerate));if (MediaPlayer-GetTime() FrameTime){while ((MediaPlayer-GetTime() FrameTime) !m_Pause);MediaPlayer-Pause();break;}}}FPlatformProcess::Sleep(0.01);}return 0; }void RNGThread::PauseThread() {m_Pause true; }void RNGThread::ContinueThread() {m_Pause false;// 启动线程if (m_semaphore){//Here is a FEvent signal Trigger() - it will wake up the thread.m_semaphore-Trigger();} }void RNGThread::Stop() {// 设置停止的标志m_Kill true; //Thread kill condition while (!m_Kill){...}m_Pause false;// 触发一下线程让其在下一次判断中退出if (m_semaphore){//We shall signal Trigger the FEvent (in case the Thread is sleeping it shall wake up!!)m_semaphore-Trigger();} }//Use this method to kill the thread!! void RNGThread::EnsureCompletion() {// 停止线程Stop();// 等待线程运行结束if (Thread){Thread-WaitForCompletion();}if (this-MediaPlayer ! nullptr){MediaPlayer nullptr;}if (this-PXVideoComponent ! nullptr){this-PXVideoComponent-UnregisterComponent();this-PXVideoComponent-DestroyComponent();this-PXVideoComponent nullptr;} }bool RNGThread::IsThreadPaused() {return (bool)m_Pause; }bool RNGThread::setMediaPlayer(UMediaPlayer* pMediaPlayer) {this-MediaPlayer pMediaPlayer;return true; } bool RNGThread::setVideoComponent(UPXVideoComponent* pPXVideoComponent) { this-PXVideoComponent pPXVideoComponent;return true; } 使用方法 启动线程 RNGThread * pThread new RNGThread(); pThread-setMediaPlayer(MediaPlayer);关闭线程 if (pThread ! nullptr) {pThread-EnsureCompletion();delete pThread;pThread nullptr; }
http://www.hkea.cn/news/14479064/

相关文章:

  • 外贸企业建网站静态网站规范
  • 广州做企业网站南宁百度seo排名优化
  • 从零开始学习网站开发计划设计网站账号
  • 网站建设方案实施word与wordpress
  • 娄底工程建设有限公司网站贴图库wordpress
  • 网站建设发展方向django mysql网站开发
  • php二次网站开发步骤网站做几个域名比较好
  • 网页制作师培训济南优化网站的哪家好
  • 国内怎么打开WordPress网站建个微网站多少钱
  • 网页设计与网站建设项目教程wordpress的主题下载
  • 不需要网站备案的广告联盟写作网站5秒不写就删除
  • 目前网站开发怎么兼顾手机吴忠市建设网站
  • 网页制作与网站建设问答题手机手机网站建设
  • 淮北市重点工程建设局网站dw网站设计模板
  • 学院网站建设申请报告h5网站制作介绍
  • 海尔电子商务网站建设预算做网站怎么办营业执照
  • 旅游网站开发系统的er图外汇做单记录做单专业网站有哪些
  • 外贸营销网站建设wordpress 名片插件
  • 做网站开发很赚钱吗wikiesu wordpress
  • 去哪儿网站建设需要哪些技术最近新闻热点事件2024
  • 戴尔网站建设的特点wordpress导航插件
  • 产品做国外网站有哪些wordpress 防止保存图片
  • 盘锦网站建设多少钱wordpress 短链插件
  • h5制作平台是什么意思京东seo搜索优化
  • dz可以做门户网站吗做网站必须要购买空间吗
  • 网站建设徐州做网站百度推广多少钱
  • 支付商城网站制作软文推广多少钱
  • 网站制作哪家专业google英文网站
  • 网站开发 图片存放宜宾seo快速排名
  • 公益广告 公司网站建设中...网站空间怎么申请