如何在不使用safari或iOS海报的情况下获取HTML5视频缩略图?

如何在不使用safari或iOS海报的情况下获取HTML5视频缩略图?,ios,html,video,safari,mp4,Ios,Html,Video,Safari,Mp4,我已经嵌入了mp4格式的HTML5视频。如何在不使用“poster”属性的情况下获得类似于海报的缩略图图像。Safari和iOS上出现了这个问题。我已经添加了视频,如下面提到的代码 <video height=350 id='TestVideo' webkit-playsinline><source src='test.mp4' type=video/mp4></video> 在Chrome浏览器(即Firefox)上,第一帧视频以缩略图的形式出现,但在

我已经嵌入了mp4格式的HTML5视频。如何在不使用“poster”属性的情况下获得类似于海报的缩略图图像。Safari和iOS上出现了这个问题。我已经添加了视频,如下面提到的代码

<video height=350 id='TestVideo' webkit-playsinline><source src='test.mp4' type=video/mp4></video>

在Chrome浏览器(即Firefox)上,第一帧视频以缩略图的形式出现,但在Safari和iOS上没有出现。

来源:

这对我很有用:

<img src="thumbnail.png" alt="thumbnail" />
/* code for the video goes here */

如果您想在不存储服务器端映像的情况下执行此操作,这是可能的,尽管有点笨重。。。使用画布录制视频的第一帧,然后将其覆盖在视频元素上。可以使用画布的URL作为海报的源(例如
video.Poster=c.toDataURL();
),但这需要正确的CORS设置(不确定视频是否在您自己的服务器上,以及您是否可以控制,所以选择了最安全的选项)。如果视频被正确地编码为流式传输,这将是最有效的(因此MOOV atom位于视频的前端,否则绘制叠加会很慢-有关更多详细信息,请参阅)

HEAD
包含视频和覆盖的样式(您需要调整大小和位置以适合您的应用程序)

最后,您需要加载视频、搜索第一帧并将视频加载到画布中的代码,然后将其插入覆盖层

<script>

function generateOverlay() {
    video.removeEventListener('seeked',generateOverlay);  / tidy up the event handler so it doesn't redraw the overlay every time the user manually seeks the video
    var c = document.createElement("canvas");
    var ctx = c.getContext("2d");
    c.width = 640;
    c.height = 264;
    ctx.drawImage(video, 0, 0, 640, 264); // take the content of the video frame and place in canvas
    overlay.appendChild(c); // insert canvas into the overlay div
}

    // identify the video and the overlay
    var video = document.getElementById("video");
    var overlay = document.getElementById("video_overlays");

    // add a handler that when the metadata for the video is loaded it then seeks to the first frame
    video.addEventListener('loadeddata', function() {
        this.currentTime = 0;
    }, false);

    // add a handler that when correctly seeked, it generated the overlay
    video.addEventListener('seeked', function() {
    // now video has seeked and current frames will show
    // at the time as we expect
        generateOverlay();
    }, false);

    // load the video, which will trigger the event handlers in turn
    video.load();

</script>

函数generateOverlay(){
video.removeEventListener('seek',generateOverlay);/整理事件处理程序,使其不会在用户每次手动查找视频时重新绘制覆盖
var c=document.createElement(“画布”);
var ctx=c.getContext(“2d”);
c、 宽度=640;
c、 高度=264;
drawImage(视频,0,0,640,264);//获取视频帧的内容并放置在画布中
appendChild(c);//将画布插入覆盖div
}
//识别视频和覆盖
var video=document.getElementById(“视频”);
var overlay=document.getElementById(“视频覆盖”);
//添加一个处理程序,当加载视频的元数据时,它将查找第一帧
video.addEventListener('loadeddata',function(){
这个.currentTime=0;
},假);
//添加一个处理程序,该处理程序在正确查找时生成覆盖
video.addEventListener('seek',function(){
//现在视频已搜索,当前帧将显示
//在我们期望的时间
generateOverlay();
},假);
//加载视频,这将依次触发事件处理程序
video.load();

这有点晚了,但我们有相同的场景。我不能使用“静音”属性,因为我的视频是播客。这就是我想到的,我希望与未来的游客分享。我所做的是将视频加载到body标记中,绘制画布,检索为base64,并将其作为背景图像应用到视频中

因为我的视频应该固定在150px的高度,所以我计算了纵横比,这样无论实际视频的高度和宽度如何,它都将调整为150px的高度和动态宽度

$('body').append('<video class="checkmeload" style="position:absolute;top:-10000px" controls preload="auto" playsinline src="//src-here"><source src="//src-here" type="//videotype-here"></video>');

$('body').find('.checkmeload').on('loadeddata', function(){
    var video = $('.checkmeload');

    var canvas = document.createElement('canvas');
    aspectratio = (video[0].videoWidth / video[0].videoHeight);
    newwidth = (150 * aspectratio);
    canvas.width = newwidth;
    canvas.height = 150;

    var context = canvas.getContext('2d');
    context.drawImage(video[0], 0, 0, canvas.width, canvas.height);
    var dataURI = canvas.toDataURL('image/jpeg');

    $('body').find('.checkmeload').remove(); 

    $('#myvideo').css('background-image','url("'+dataURI +'")');
});
$('body')。追加(“”);
$('body').find('.checkmeload').on('loadeddata',function()){
var video=$('.checkmeload');
var canvas=document.createElement('canvas');
aspectratio=(视频[0]。视频宽度/视频[0]。视频高度);
新宽度=(150*aspectratio);
canvas.width=newwidth;
帆布高度=150;
var context=canvas.getContext('2d');
context.drawImage(视频[0],0,0,canvas.width,canvas.height);
var dataURI=canvas.toDataURL('image/jpeg');
$('body').find('.checkmeload').remove();
$('#myvideo').css('background-image','url('+dataURI+'));
});
只需在
视频中添加
preload=“metadata”
标记,并在url src处设置
#t=0.1
,它将以缩略图的形式获取视频的0.1s帧

但是,此解决方案的缺点是,当您单击播放视频时,它总是从0.1s开始

<video preload="metadata" controls>
    <source src="video.mp4#t=0.1" type="video/mp4">
</video>


你能添加你的代码吗?有一个带有autoplay的解决方案,但它只能在IOS 10+中工作。谢谢,但我不想为视频使用单独的图像或海报,因为视频是动态的,我不想通过添加单独的图像来返工。你有没有办法将视频集的第一帧作为海报。没有,我可以使用哪个插件?它叫popcorn.js。检查以下两个链接:你能想出一个解决方案吗?谢谢,我会试试popcorn.js。这种方法效果非常好。我在iOS上使用它没有问题。在Chrome Androïd和桌面上进行测试,到目前为止没有问题。谢谢你的想法。如果你使用blob.url作为视频,这个方法就不起作用了。这个聪明的方法完美地工作了,并且解决了我长期以来的问题:一旦剪辑加载完成,本地缩略图就会显示出来!非常感谢你!它还根据需要替换poster属性,并且0.1s偏移在我的用例中并不重要,因此这是我的用例的完美解决方案。
<script>

function generateOverlay() {
    video.removeEventListener('seeked',generateOverlay);  / tidy up the event handler so it doesn't redraw the overlay every time the user manually seeks the video
    var c = document.createElement("canvas");
    var ctx = c.getContext("2d");
    c.width = 640;
    c.height = 264;
    ctx.drawImage(video, 0, 0, 640, 264); // take the content of the video frame and place in canvas
    overlay.appendChild(c); // insert canvas into the overlay div
}

    // identify the video and the overlay
    var video = document.getElementById("video");
    var overlay = document.getElementById("video_overlays");

    // add a handler that when the metadata for the video is loaded it then seeks to the first frame
    video.addEventListener('loadeddata', function() {
        this.currentTime = 0;
    }, false);

    // add a handler that when correctly seeked, it generated the overlay
    video.addEventListener('seeked', function() {
    // now video has seeked and current frames will show
    // at the time as we expect
        generateOverlay();
    }, false);

    // load the video, which will trigger the event handlers in turn
    video.load();

</script>
$('body').append('<video class="checkmeload" style="position:absolute;top:-10000px" controls preload="auto" playsinline src="//src-here"><source src="//src-here" type="//videotype-here"></video>');

$('body').find('.checkmeload').on('loadeddata', function(){
    var video = $('.checkmeload');

    var canvas = document.createElement('canvas');
    aspectratio = (video[0].videoWidth / video[0].videoHeight);
    newwidth = (150 * aspectratio);
    canvas.width = newwidth;
    canvas.height = 150;

    var context = canvas.getContext('2d');
    context.drawImage(video[0], 0, 0, canvas.width, canvas.height);
    var dataURI = canvas.toDataURL('image/jpeg');

    $('body').find('.checkmeload').remove(); 

    $('#myvideo').css('background-image','url("'+dataURI +'")');
});
<video preload="metadata" controls>
    <source src="video.mp4#t=0.1" type="video/mp4">
</video>