3

我很难找到这是否可能(在任何地方都找不到信息)。是否可以在视频上传期间提取帧(缩略图)?如果可以提取用户端,则使用 jscript 提取也是一种选择。

谢谢您的帮助!

4

5 回答 5

7

自这个问题发布以来快进快五年了,现在答案是肯定的!

现场演示

如何使用 JavaScript 在视频上传期间提取帧

在显示代码之前,这是我们要做的:

  1. 在将上传视频的输入元素上设置一个事件处理程序
  2. 当从文件系统中选择一个文件时,使用该URL对象创建一个指向本地视频文件的 url。
  3. 将该 URL 加载到video元素中。
  4. canvas当视频加载到内存中时,在对象上绘制一个框架。
  5. 现在将画布上渲染的帧导出到一个image元素中(或者选择将该图像作为数据 url 发送到您的服务器)。

<input type="file" id="upload"/>
<img id="thumbnail"/>

<script>
var input = document.getElementById('upload');
var img = document.getElementById('thumbnail');

input.addEventListener('change', function(event){
    var file = this.files[0];
    var url = URL.createObjectURL(file);

    var video = document.createElement('video');
    video.src = url;

    var snapshot = function(){
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');

        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        img.src = canvas.toDataURL('image/png');

        video.removeEventListener('canplay', snapshot);
    };

    video.addEventListener('canplay', snapshot);
});
</script>
于 2016-03-16T20:57:14.257 回答
0

我不认为在 php 中有一个很好的方法来做到这一点。(https://stackoverflow.com/a/1309425/1488032

如果它不仅仅是您租用的一些网络空间,而且有权在服务器上安装和运行其他软件,我建议使用 ffmpeg 之类的东西,并使用system()passthru()exec()从 php 中调用它来提取您想要的内容,然后再次在 php 中进行其余处理。

我正在运行一个依赖于嵌入在 xhtml 中的 svg 图像的浏览器游戏,但某些浏览器(尤其是移动浏览器)不支持完整的 svg 语法。在这种情况下,我使用这样的system()调用使用 imagemagick 的转换二进制文件进行 svg 到 png 的转换,并将结果显示在我的页面上。

system("echo '$svgString' | convert svg:- png:- | base64");

我想你必须退回到类似的东西。

以下是使用 ffmpeg 提取帧的一些信息: http ://ubuntuforums.org/showthread.php?t=1141293

于 2012-06-29T12:40:32.947 回答
0

Javascript:没有。

上传期间:没有。

上传后,是的。

“Dev”在评论中提供了正确的链接,但您应该将视频保存到您的服务器,然后运行 ​​ffMpeg 来抓取图像。您可以在此处下载 ffMPEG:http://ffmpeg.org/download.html 如果您对自己构建没有信心,请获取所需的构建 - 有 Linux 和 Windows 构建)。

文档在这里: http: //ffmpeg.org/ffmpeg.html但是在http://linuxers.org/tutorial/how-extract-images-video-using-ffmpeg有一个更容易阅读的教程来获取一个图片。

注意:有一个 PHP 扩展名为“phpFFMPEG”,但我建议你不要使用它。只需通过 PHP 中的“exec()”运行所需的命令。检查错误返回值,因为每个 CPU 内核只能运行一次 ffMPEG,因此如果同时尝试两次,它可能会失败 - 将操作排队或在失败时重试。

于 2012-06-29T12:50:35.563 回答
0

首先,您需要选择一个程序来提取框架。ffmpeg 通常用于此目的。无论您选择什么,它都需要能够处理部分文件内容。

php脚本直到整个文件上传完成后才开始执行,但是php最近有了一个功能,可以在文件上传期间执行不同的php脚本,并且能够获取上传脚本数据(文件名是事情你感兴趣)。 http://php.net/manual/en/session.upload-progress.php

然后,基本上调用外部程序从监控脚本中提取帧,使用上传处理脚本中上传的临时文件名。

总结:将文件上传到upload.php. monitor.php将获取正在上传的临时文件名upload.php,并提取框架。

于 2012-06-29T16:16:54.093 回答
0

基本上,我采用了此线程中提供的 rodrigo-silveira 答案并对其进行了修改以供我使用,现在该解决方案就像一个魅力。即使我试图上传用户希望上传的视频的视频缩略图/海报,并将视频和缩略图保存在文件夹中。另外,我不想使用ffmpeg。

这是我所做的:在名为“upload.php”的上传文件中,我有以下代码,对上面的rodrigo-silveira的解决方案稍作修改:

上传.php:

<input type="file" id="upload"/>
<img id="thumbnail"/>

<form action="action_page.php" method="post" target="_blank">
<input type="hidden" id="mytext" name="mytext" >
<input type="submit" value="Submit">
</form>

<script>
var input = document.getElementById('upload');
var img = document.getElementById('thumbnail');

input.addEventListener('change', function(event){
    var file = this.files[0];
    var url = URL.createObjectURL(file);

    var video = document.createElement('video');
    video.src = url;

    var snapshot = function(){
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
		canvas.width = 350;
		canvas.height = 250;
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        img.src = canvas.toDataURL('image/png');
		document.getElementById("mytext").value = img.src;
        video.removeEventListener('canplay', snapshot);
    };
	
    video.addEventListener('canplay', snapshot);
});
</script>

上面的 HTML 部分和 JavaScript 都在 upload.php 的 body 标记中。

现在进入 action_page.php 文件:

<?php
$data = $_POST['mytext'];
$file = "photos/file".time().".png";
$uri = substr($data,strpos($data, ",") + 1);
file_put_contents($file, base64_decode($uri));
?>

将两个 PHP 文件保存在同一个文件夹中,并在该文件夹中创建另一个名为“photos”的文件夹。您在 upload.php 页面中选择的视频中的视频缩略图/海报图像将作为 png 文件保存在“照片”文件夹中。(注意:此解决方案不上传视频,只上传视频缩略图。但从这里开始就很简单了。)

于 2018-05-31T01:55:02.720 回答