看三屏网课视频不同步的解决方法(vga和asf)
文章目录
- 问题
- 解决方法一(不好用)
- 解决方法二(舍弃)
- 解决方法三(通用)
- 总结
- 附录
- 成品代码
- frmleftup.htm原本文件的源代码
问题
为了学习Windows编程,最近在看《高级Windows程序设计——中科院(杨力祥)》的网课视频。这个网课制作的比较早,是用三屏方案制作的:
其中,1是授课的视频,2是课件的录屏,3是概要跳转。
在学习的过程中,我发现有几节课里,授课视频和课件录屏不同步,两者有几分钟的延迟,遂开始寻找解决方法。
一节网课的文件目录如下:
其中,
- 授课视频文件,可以用视频播放软件打开,在网页上采用的是Windows Media Player插件控制;
- 控制授课视频的网页文件,授课视频的基本架构在这里,同步控制授课视频和课件录屏的函数也在这里,本次修改只改该文件。
- 课件录屏文件,格式是vga,一种比较早的文件格式,可以用VGAPlayer软件播放,我本次修改遇到的最大阻碍就出在这。
- VGAPlayer插件,如果没有这个网页是解码不了vga文件的,甚至FFmpeg也不行。若网课播放不了,请检查是否缺失该插件。
- 总的网页文件,点击后将入网课界面。
解决方法一(不好用)
找到了授课视频文件和课件录屏文件,我尝试用最简单的方法:分别播放两个文件,通过调整时间来同步,如下图所示:
这样做的缺点很明显,小幅度的同步跳转会很麻烦,调整进度条的时候很麻烦,且丧失了概要跳转功能。
解决方法二(舍弃)
因为这种形式的网课现在已经不常见了,我再遇上这类网课的类似问题的可能性不大,我便想通过取巧的方式快捷地解决这个问题。我开始尝试第二种方法:通过比较两个视频的时长,我发现不同步的问题多是课件录屏的时长比授课视频的时长多了几分钟造成的。有两种解决方案:1,通过剪辑软件增加授课视频的时长;2,通过剪辑软件减少课件录屏的时长。
实践中发现,受我电脑条件的制约,第一种方案在生成目标视频时耗时过长,遂舍弃。电脑可以快速生成剪辑后的视频的朋友可以试一试。
在搜索的时候我发现,vga这种视频格式是由北京翰博尔公司制定的(这是它现在的官网),还没有开源,vga只可以用它自家的软件播放和编辑,其他的播放器(比如potplayer)是无法播放的。可以用vga player播放,据说可以用PowerCreator Media Studio这个软件剪辑,但我找不到PowerCreator Media Studio这个软件的下载地址,只找到了这篇博文,无法进一步验证。
搜索时看到有人说可以用暴风影音编辑vga,尝试后发现是实现不了的。
由于得不到能编辑课件录屏的软件,遂舍弃第二种方案。
解决方法三(通用)
于是我考虑通过阅读源码,直接增加一个同步功能,参照播放器常见的音频同步功能。成品代码在附录部分。
经过阅读源码,我找到了控制授课视频的htm文件——frmleftup.htm,它的源代码在附录部分。它实现授课视频和课件录屏同步播放的思路是:通过定时器,每隔1秒进行检查,当前授课视频的位置秒数是否和课件录屏的位置秒数相差0.3秒以上,若大于0.3秒,则以授课视频的位置秒数为准,将其赋值给课件录屏。这段代码具体为:
<script language="javascript">
function Syn()
{TimerID = setTimeout("Syn()",1000);if (Math.abs(parent.RightFrame.VGAPlayer.CurrentPosition - MediaPlayer.Controls.currentPosition * 1000) >= 300) {parent.RightFrame.VGAPlayer.CurrentPosition = MediaPlayer.Controls.currentPosition * 1000;}if ( (MediaPlayer.playState == mpPlaying) && (parent.RightFrame.VGAPlayer.Status != 2) ){parent.RightFrame.VGAPlayer.Play(); }
}
</script>
思路就有了,设置一个变量记录要增加或减少(减少即为负值)的时间差值,在每次检查同步时,将这个变量与授课视频位置秒数的和赋值给课件录屏,就能实现可控秒数的同步。上述段代码就修改为:
<script language="javascript">
//同步授课视频和课件录屏
function Syn()
{TimerID = setTimeout("Syn()",1000);//每当授课视频和课件录屏相差300+延时时间(毫秒)时,将两个视频同步(要加上延时时间),以授课视频的时间为准if (Math.abs(parent.RightFrame.VGAPlayer.CurrentPosition - MediaPlayer.Controls.currentPosition * 1000 - late_second) >= 300) {parent.RightFrame.VGAPlayer.CurrentPosition = MediaPlayer.Controls.currentPosition * 1000 + late_second;}if ( (MediaPlayer.playState == mpPlaying) && (parent.RightFrame.VGAPlayer.Status != 2) ){parent.RightFrame.VGAPlayer.Play(); }
}
</script>
当授课视频的进度条被拉动时,为了保证课件录播也跳到相应的位置,原文件提供的解决办法是:通过响应mediaplayer插件预设的进度条事件,以授课视频拉动后的位置秒数为准,将其赋值给课件录屏。该段代码如下:
<script language="javascript" FOR="MediaPlayer" EVENT="PositionChange(dblOldPosition, dblNewPosition)">parent.RightFrame.VGAPlayer.CurrentPosition = dblNewPosition * 1000;
</script>
为了能在进度条被拉动时仍能保证可控秒数的同步,要将新位置秒数与时间差值的和赋值给课件录屏。
<script language="javascript" FOR="MediaPlayer" EVENT="PositionChange(dblOldPosition, dblNewPosition)">//当授课视频的进度条被拉动时,确保课件录屏的时间也会跳转到相应的位置(要加上延迟时间)parent.RightFrame.VGAPlayer.CurrentPosition = dblNewPosition * 1000 + late_second;
</script>
为了能在网页界面上控制时间差值,要在网页上增加几个控件。我选择了输入框和两个按钮,输入框用来输入时间差值,两个按钮实现对时间差值加一秒或减一秒。默认是隐藏起来的,当需要输入时,鼠标移动到上方便会显示:
<!-- 通过响应鼠标事件来实现显示输入框和按钮,选择空格是为了美观 -->
<p onmouseover='show_input()' onmouseout='save_display()'>
<input id='input1' type="text" style='display:none' value="0">
<button id='but2' style='display:none' onclick='add_second()'>+1s</button>
<button id='but3' style='display:none' onclick='subtract_second()'>-1s</button>
</p>
<script>
//保存延时时间,单位毫秒
var late_second = 0;
//显示输入框和按钮
function show_input(){document.getElementById('input1').style.display = 'inline';document.getElementById('but2').style.display = 'inline';document.getElementById('but3').style.display = 'inline';
}
//隐藏输入框和按钮
//将输入框里获取的字符转换为数字,单位换算为毫秒,赋值给late_second
function save_display(){document.getElementById('input1').style.display = 'none';document.getElementById('but2').style.display = 'none';document.getElementById('but3').style.display = 'none';late_second = Number(document.getElementById('input1').value)*1000;
}
function add_second(){document.getElementById('input1').value = Number(document.getElementById('input1').value)+1;late_second = Number(document.getElementById('input1').value)*1000;
}
function subtract_second(){document.getElementById('input1').value = Number(document.getElementById('input1').value)-1;late_second = Number(document.getElementById('input1').value)*1000;
}
</script>
为了能在页面上放下上述控件,我又修改了播放器控件的高度百分比,从100%调到90%:
<script language="javascript">
if (Photo != "")
{//调整了播放器控件的显示高度,以及对齐方向document.writeln("<object align=left classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='90%'>"); document.writeln(" <param name='windowlessVideo' value='-1'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");ShowPhoto(Photo);
}
else
{//调整了播放器控件的显示高度,以及对齐方向document.writeln("<object align=left classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='90%'>"); document.writeln(" <param name='windowlessVideo' value='0'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");
}
</script>
默认效果如下:
(鼠标移动到左上角,显示按钮和输入框)
我一般会拉动边框来调整成这个大小:
(鼠标移动到左上角,显示按钮和输入框)
总结
只要是采用了该类三屏解决方案的网课,基本上视频不同步的问题都可以用以上方法解决。
本来想再增加一个功能:刚进入页面执行一次,通过比较两个视频的时长,自动计算差值并同步。但我查找不到使用vga插件获取时长的参考资料,也没有找到官方文档,遂放弃了该功能。
附录
成品代码
以下代码可直接使用,需新创建一个frmleftup.htm文件,将以下代码粘贴到该文件内并保存,再替换掉原本的frmleftup.htm文件。
不知道是什么原因,在csdn的安卓端上以下代码大概率只会显示前83行,83行以后的显示不出来(猜测是代码颜色变成了背景色),但仍能选择、复制。网页端查看以下代码是没有出现上述问题的。
<html>
<head>
<title>Video</title>
<script language="javascript">
if (window.name != "LeftupFrame") location = "content.htm";
</script>
<script src=config.js></script>
<script src=func.js></script>
</head><script language="javascript">
var mpStopped=1, mpPaused=2, mpPlaying=3,mpScanForward=4, mpScanReverse=5, mpEnded=8,NeverUpdatePosition=1,TimerID=0,Waiting=0,WaitingCount=0,AsxFileName;
</script><script>
//保存延时时间,单位毫秒
var late_second = 0;
//显示输入框和按钮
function show_input(){document.getElementById('input1').style.display = 'inline';document.getElementById('but2').style.display = 'inline';document.getElementById('but3').style.display = 'inline';
}
//隐藏输入框和按钮
//将输入框里获取的字符转换为数字,单位换算为毫秒,赋值给late_second
function save_display(){document.getElementById('input1').style.display = 'none';document.getElementById('but2').style.display = 'none';document.getElementById('but3').style.display = 'none';late_second = Number(document.getElementById('input1').value)*1000;
}
function add_second(){document.getElementById('input1').value = Number(document.getElementById('input1').value)+1;late_second = Number(document.getElementById('input1').value)*1000;
}
function subtract_second(){document.getElementById('input1').value = Number(document.getElementById('input1').value)-1;late_second = Number(document.getElementById('input1').value)*1000;
}
</script><script language="javascript" FOR="window" EVENT="onload">
//Load ASF File
if(document.location.protocol == "file:") AsxFileName = "localclip.asx";
else AsxFileName = "remoteclip.asx";
MediaPlayer.URL = AsxFileName;
</script><script language="javascript">
//同步授课视频和课件录屏
function Syn()
{TimerID = setTimeout("Syn()",1000);//每当授课视频和课件录屏相差300+延时时间(毫秒)时,将两个视频同步(要加上延时时间),以授课视频的时间为准if (Math.abs(parent.RightFrame.VGAPlayer.CurrentPosition - MediaPlayer.Controls.currentPosition * 1000 - late_second) >= 300) {parent.RightFrame.VGAPlayer.CurrentPosition = MediaPlayer.Controls.currentPosition * 1000 + late_second;}if ( (MediaPlayer.playState == mpPlaying) && (parent.RightFrame.VGAPlayer.Status != 2) ){parent.RightFrame.VGAPlayer.Play(); }
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="Buffering(Start)">
if (Start)
{parent.RightFrame.VGAPlayer.Pause();
}
else
{parent.RightFrame.VGAPlayer.Play();
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="playStateChange(NewState)">
switch(NewState)
{case mpPlaying: parent.RightFrame.document.all.VGAPlayer.Play();if (TimerID == 0) Syn();break;case mpPaused:parent.RightFrame.document.all.VGAPlayer.Pause();break;case mpStopped:parent.RightFrame.document.all.VGAPlayer.Stop();break;case mpEnded:parent.RightFrame.document.all.VGAPlayer.Stop();
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="PositionChange(dblOldPosition, dblNewPosition)">//当授课视频的进度条被拉动时,确保课件录屏的时间也会跳转到相应的位置(要加上延迟时间)parent.RightFrame.VGAPlayer.CurrentPosition = dblNewPosition * 1000 + late_second;
</script><body bgcolor="black"><!-- 通过响应鼠标事件来实现显示输入框和按钮,选择空格是为了美观 -->
<p onmouseover='show_input()' onmouseout='save_display()'>
<input id='input1' type="text" style='display:none' value="0">
<button id='but2' style='display:none' onclick='add_second()'>+1s</button>
<button id='but3' style='display:none' onclick='subtract_second()'>-1s</button>
</p><script language="javascript">
if (Photo != "")
{//调整了播放器控件的显示高度,以及对齐方向document.writeln("<object align=left classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='90%'>"); document.writeln(" <param name='windowlessVideo' value='-1'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");ShowPhoto(Photo);
}
else
{//调整了播放器控件的显示高度,以及对齐方向document.writeln("<object align=left classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='90%'>"); document.writeln(" <param name='windowlessVideo' value='0'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");
}
</script></body></html>
frmleftup.htm原本文件的源代码
不知道是什么原因,在csdn的安卓端上以下代码大概率只会显示前83行,83行以后的显示不出来(猜测是代码颜色变成了背景色),但仍能选择、复制。网页端查看以下代码是没有出现上述问题的。
<html>
<head>
<title>Video</title>
<script language="javascript">
if (window.name != "LeftupFrame") location = "content.htm";
</script>
<script src=config.js></script>
<script src=func.js></script>
</head><script language="javascript">
var mpStopped=1, mpPaused=2, mpPlaying=3,mpScanForward=4, mpScanReverse=5, mpEnded=8,NeverUpdatePosition=1,TimerID=0,Waiting=0,WaitingCount=0,AsxFileName;
</script><script language="javascript" FOR="window" EVENT="onload">
//Load ASF File
if(document.location.protocol == "file:") AsxFileName = "localclip.asx";
else AsxFileName = "remoteclip.asx";
MediaPlayer.URL = AsxFileName;
</script><script language="javascript">
function Syn()
{TimerID = setTimeout("Syn()",1000);if (Math.abs(parent.RightFrame.VGAPlayer.CurrentPosition - MediaPlayer.Controls.currentPosition * 1000) >= 300) {parent.RightFrame.VGAPlayer.CurrentPosition = MediaPlayer.Controls.currentPosition * 1000;}if ( (MediaPlayer.playState == mpPlaying) && (parent.RightFrame.VGAPlayer.Status != 2) ){parent.RightFrame.VGAPlayer.Play(); }
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="Buffering(Start)">
if (Start)
{parent.RightFrame.VGAPlayer.Pause();
}
else
{parent.RightFrame.VGAPlayer.Play();
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="playStateChange(NewState)">
switch(NewState)
{case mpPlaying: parent.RightFrame.document.all.VGAPlayer.Play();if (TimerID == 0) Syn();break;case mpPaused:parent.RightFrame.document.all.VGAPlayer.Pause();break;case mpStopped:parent.RightFrame.document.all.VGAPlayer.Stop();break;case mpEnded:parent.RightFrame.document.all.VGAPlayer.Stop();
}
</script><script language="javascript" FOR="MediaPlayer" EVENT="PositionChange(dblOldPosition, dblNewPosition)">parent.RightFrame.VGAPlayer.CurrentPosition = dblNewPosition * 1000;
</script><body bgcolor="black"><script language="javascript">
if (Photo != "")
{document.writeln("<object align=right classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='100%'>"); document.writeln(" <param name='windowlessVideo' value='-1'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");ShowPhoto(Photo);
}
else
{document.writeln("<object align=right classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 id=MediaPlayer width='100%' height='100%'>"); document.writeln(" <param name='windowlessVideo' value='0'>");document.writeln(" <param name='stretchToFit' value='-1'>");document.writeln("</object>");
}
</script></body>
</html>
看三屏网课视频不同步的解决方法(vga和asf)相关推荐
- 录制计算机网课,自己怎么录制网课视频?
原标题:自己怎么录制网课视频? 现代人上网课的情况越来越普遍了,特别是最一段时间学校停课的时间很长,很多人只能通过上网课的形式来补充知识.而许多网课视频是及时性的,没有任何保存下来的途径,这时候我们想 ...
- 【网课视频提取ppt】【原创好用】如何自动提取视频中的PPT画面?网课视频提取ppt教程
本文介绍了一款名为"Gleamoe Peanut 2023"的软件,可用于自动从网课视频中提取PPT画面. 软件手册:https://gleamore.feishu.cn/docx ...
- Windows 10 IDM 下载play.kth.se上面的网课视频
鉴于现在的疫情,KTH也停止了线下授课,改为网课教学. 而play.kth.se也成为了视频上传的首选地. 如果想要下载视频,留待以后观看(自行),或者是有需要离线观看视频的刚需,那么你来对地方了. ...
- 二建课件网课视频下载二建证书为什么现在不能立即实行“全国执业”?
二建课件网课视频下载二建证书为什么现在不能立即实行"全国执业"? 对于二级建造师证书只能省内注册,省内使用.很多考生就很羡慕一级建造师证书可以全国注册,全国使用.那么如果二级建造师 ...
- 视频损坏修复后卡顿声音画面口型不同步处理解决方法
视频修复后为什么会 出现卡顿.花屏.音画不同步? 视频损坏后经简单修复后经常遇到画面卡顿,甚至会有花屏,声音和视频画面(说话口型)不同步的情况,声音或者画面提早或者滞后出现,视觉效果上会有明显差别,是 ...
- 计算机蓝屏后无法启动不了,win10电脑蓝屏后不能启动不了系统解决方法
在win10系统中使用ACDsee软件的时候,有网友遇到了打开ACDsee软件看图时,电脑变成蓝屏,并且无法再启动,屏幕上错误代码为kernel_security_check_failure,这该怎么 ...
- mp4视频无法播放的解决方法
mp4视频是我们日常工作生活中经常会遇到的视频格式,但如果遇到重要的mp4视频无法播放了,该怎么办呢?有mp4视频无法播放的解决方法吗?下面小编为大家整理了这个问题产生的原因以及相应的解决方法,让我们 ...
- android电视直播卡顿,电视盒子看直播卡顿原因分析以及教你解决方法!
原标题:电视盒子看直播卡顿原因分析以及教你解决方法! 其实关于智能机顶盒.智能电视大家最想了解的就是想知道到底能不能流畅的看直播.看视频电影,这里我可以很负责的告诉大家:想要高清.完全不卡顿的看直播电 ...
- C语言运行时电脑白屏怎么办,win10电脑白屏死机无响怎么回事_win10电脑白屏死机无响七种解决方法...
win10专业版使用一段时间后出现白屏死机的问题,开机后不是登录界面,而是白色屏幕,尝试多次还是一样,怎么办呢?此故障原因无非是硬件或软件两大原因,有什么办法解决呢?此文小编告诉大家解决win10电脑 ...
最新文章
- CentOs7安装gitlab(转!)
- 基于visual Studio2013解决面试题之0402合并升序链表并去重
- Authid current_user的用法
- 异步调用WebService方式!
- array python 交集_模糊数学Python库简介和评测
- 前端学习(2694):重读vue电商网站15之阻止页签tabs切换
- 01.神经网络和深度学习 W4.深层神经网络(作业:建立你的深度神经网络+图片猫预测)
- XML--可扩展标记语言
- 第三章 垃圾收集器与内存分配策略(待续)
- Android ViewFilpper实现分页效果
- 花小钱办大事 888元血汗钱如何装电脑
- 德卡Z90读卡器读取社保卡,德卡Z90读卡器CSharp示例程序源码
- npm 安装vue脚手架报错警告npm WARN deprecated
- pidgin linux,Linux下的IM(Pidgin,EVA,QQlinux,...)
- phusion passenger standalone
- html风琴图片展示,基于jquery的手风琴图片展示效果实现方法
- Velodyne 64线激光雷达协议
- 【数据结构】顺序表详解 | 从零开始步步解读 | 画图理解并调试分析
- 史上最强!PC时代的20位英雄
- 金蝶EAS开发认证考试