即时加载视频

Posted

技术标签:

【中文标题】即时加载视频【英文标题】:Loading videos on-the-fly 【发布时间】:2015-03-25 22:36:24 【问题描述】:

我在网络编程方面相对较新,因此在保持我的代码清洁方面存在问题。在处理最后一个项目时,除其他事项外,我必须执行以下操作:

    在主页上自动播放八个可用视频之一(例如 main-vid-3.webm); 当它结束时,开始播放下一个(在这种情况下,main-vid-4.webm); 然后播放下一个视频,依此类推。在第八个视频之后,必须播放 main-vid-1。

如果我在上一个视频结束后立即开始播放下一个视频,我会出现延迟,因为尚未加载新视频。我的问题解决方法:

    页面上有两个视频标签,其中一个有 display: none; 当带有 display: 块的视频结束时,它会隐藏,而另一个视频出现并开始播放; 播放该视频时,隐藏视频的来源随 JS 变化并开始加载(但尚未播放); 重复步骤 2;

它起作用了,但是我的代码(尤其是 JS 部分和在页面上必须有两个视频标签)对我来说似乎并不干净和好。有没有更好的解决问题的方法?

<section id="main-page-top">
		<video id="bgvid-<?php echo $vidId; ?>" autoplay >
			<source src="<?php echo get_template_directory_uri(); ?>/inc/main-vid-<?php echo $vidId; ?>.webm" type="video/webm">
		</video>
		<video id="bgvid-<?php echo ($vidId + 1); ?>" class="hidden" >
			<source src="<?php echo get_template_directory_uri(); ?>/inc/main-vid-<?php echo $vidIdAlt; ?>.webm" type="video/webm">
		</video>
</section>

document.getElementById('#main-page-top video:nth-child(1)').addEventListener('ended', function() 
  document.getElementById('#main-page-top video:nth-child(1)').style.display = "none";
  document.getElementById('#main-page-top video:nth-child(2)').style.display = "block";
  document.getElementById('#main-page-top video:nth-child(2)').play();
  var vidNum = parseInt(document.getElementById('#main-page-top video:nth-child(1)').id.substring(6));
  if (vidNum === 7) 
    vidNum = -1;
   else if (vidNum === 8) 
    vidNum = 0;
  
  document.getElementById('#main-page-top video:nth-child(1)').setAttribute('id', 'bgvid-' + (vidNum + 2));
  document.getElementById('#main-page-top video:nth-child(1) source').setAttribute('src', 'http://u0065000.isp.regruhosting.ru/template/inc/main-vid-' + (vidNum + 2) + '.webm');
  document.getElementById('#main-page-top video:nth-child(1)').setAttribute("poster", "http://u0065000.isp.regruhosting.ru/template/inc/main-vid-" + (vidNum + 2) + ".jpg");
  document.getElementById('#main-page-top video:nth-child(1)').load();
  document.getElementById('#main-page-top video:nth-child(1)').pause();
);

document.getElementById('#main-page-top video:nth-child(2)').addEventListener('ended', function() 
  document.getElementById('#main-page-top video:nth-child(2)').style.display = "none";
  document.getElementById('#main-page-top video:nth-child(1)').style.display = "block";
  document.getElementById('#main-page-top video:nth-child(1)').play();
  var vidNum = parseInt(document.getElementById('#main-page-top video:nth-child(2)').id.substring(6));
  if (vidNum === 7) 
    vidNum = -1;
   else if (vidNum === 8) 
    vidNum = 0;
  
  document.getElementById('#main-page-top video:nth-child(2)').setAttribute('id', 'bgvid-' + (vidNum + 2));
  document.getElementById('#main-page-top video:nth-child(2) source').setAttribute('src', 'http://u0065000.isp.regruhosting.ru/template/inc/main-vid-' + (vidNum + 2) + '.webm');
  document.getElementById('#main-page-top video:nth-child(2)').setAttribute("poster", "http://u0065000.isp.regruhosting.ru/template/inc/main-vid-" + (vidNum + 2) + ".jpg");
  document.getElementById('#main-page-top video:nth-child(2)').load();
  document.getElementById('#main-page-top video:nth-child(2)').pause();
);

【问题讨论】:

两个视频标签部分很好,可能需要,但另一部分重复过度,您使用的是 getElementById() 而不是 querySelector() 嗯,之前是querySelector(),所以id前面的括号里有#。我刚刚阅读了 jsperf.com/getelementbyid-vs-queryselector/11 的文章,测试表明 getElementById 在像我这样的情况下工作得更快,所以我决定更改代码。稍后我将删除所有哈希标签。 两者的表现都是没有意义的;请注意,jsperf 执行了数百万次运行,而您执行了几十次。我想说的更大一点是,您只需要调用一两次这样的方法而不是几十次,并且重新使用元素 ref 将彻底清理您的代码。只需定义,例如 var e2=document.getElementById('#main-page-top video:nth-child(2)'),然后将所有出现的冗长行替换为 e2,例如:e2.load(); e2.pause(); 正如@dandavis 所说,我认为两个视频标签方法很好,实际上非常优雅。如果您确实想转向不涉及 2 个标签的解决方案(并且如果您喜欢复杂的 javascript 代码!)html5 媒体源扩展机制应该允许您执行类似的操作 - 请参阅此答案以获得概述:***.com/a/28717239/334402。再一次,以防万一不清楚 - 我个人会坚持你的两个标签解决方案...... 【参考方案1】:

谢谢你们。我找不到是否可以将您的 cmets 标记为正确答案。

现在代码是这样的(添加了淡入淡出的功能):

var vidFading = function(p1, p2) 
    $(p1).on('timeupdate', function(event) 
        var current = Math.round(event.target.currentTime * 1000);
        var total = Math.round(event.target.duration * 1000);

        if ((total - current) < 500) 
            $(this).fadeOut("slow");
            $(p2).fadeIn(1000);
        
    );

var vidFoo = function(p1, p2) 
    var x = document.querySelector(p1);
    var x1 = document.querySelector(p1 + ' source')
    var y = document.querySelector(p2);
    y.play();
    var vidNum = parseInt(document.querySelector(p1).id.substring(6));
    if (vidNum === 7) 
        vidNum = -1;
     else if (vidNum === 8) 
        vidNum = 0;
    
    x.setAttribute('id', 'bgvid-' + (vidNum + 2));
    x1.setAttribute('src', 'http://u0065000.isp.regruhosting.ru/template/inc/main-vid-' + (vidNum + 2) + '.webm');
    x.setAttribute("poster", "http://u0065000.isp.regruhosting.ru/template/inc/main-vid-" + (vidNum + 2) + ".jpg");
    x.load();
    x.pause();



if (document.getElementById('main-page')) 

    vidFading('#main-page-vid video:nth-child(1)', '#main-page-vid video:nth-child(2)');
    vidFading('#main-page-vid video:nth-child(2)', '#main-page-vid video:nth-child(1)');

    document.querySelector('#main-page-vid video:nth-child(1)').addEventListener('ended', function() 
        vidFoo('#main-page-vid video:nth-child(1)', '#main-page-vid video:nth-child(2)');
    );

    document.querySelector('#main-page-vid video:nth-child(2)').addEventListener('ended', function() 
        vidFoo('#main-page-vid video:nth-child(2)', '#main-page-vid video:nth-child(1)');
    );

【讨论】:

以上是关于即时加载视频的主要内容,如果未能解决你的问题,请参考以下文章

如何播放即时加载的声音

多线程下单例模式:懒加载(延迟加载)和即时加载

linq之延迟加载和即时加载+标准查询运算符

即时访问大文件中的行,无需加载文件

即时加载 Amazon MP3 小部件

重新加载模块后Python中的对象类型转换? [用于即时代码更改]