如何使用 JavaScript 减少视频的长度? [关闭]
Posted
技术标签:
【中文标题】如何使用 JavaScript 减少视频的长度? [关闭]【英文标题】:How to reduce the length of a video using JavaScript? [closed] 【发布时间】:2016-12-12 21:25:20 【问题描述】:我正在尝试从头或尾修剪浏览器中视频的长度。我目前拥有的是一个使用 MediaRecorder API 录制的 MediaStream,我使用它在录制结束时生成一个 Blob,类型设置为“video/mp4”。这很好用,我可以播放视频,但是我想要一种在开始或结束时修剪视频的方法。
在对 MediaStream API 进行进一步调查后,我发现了 SourceBuffer 对象,您可以从 MediaStreamTrack 获取该对象并使用它来删除时间片,这正是我想要的。但是我不确定如何从视频(blob)中获取 MediaStreamTrack,因为 video.srcObject 属性返回 null。
【问题讨论】:
您是要删除部分视频以播放编辑后的视频,还是提供编辑后的视频以供下载? 有趣的问题。这家伙提到媒体片段是一种可能的解决方案。 ***.com/a/16992434/1567255我自己没试过。 @guest271314 both...Kosch 嗯,这似乎是一种只在特定时间部分播放视频的方法(这是我想要的一部分),但不能真正修剪文件本身,谢谢不过。 @naughtyboy "我目前拥有的是一个使用 MediaRecorder API 录制的 MediaStream,我使用它在录制结束时生成一个 Blob,类型设置为 'video/ mp4'" 你能在问题中加入javascript
吗?
<video>
src
是否在getUserMedia()
成功回调处理程序中设置为stream
?
【参考方案1】:
我正在尝试在浏览器中修剪视频的长度,从 无论是开头还是结尾。
您可以使用Array.prototype.slice()
以一秒1000ms
的数据块或其他时间范围删除包含在MediaRecorder
dataavailable
事件中的数组的包含blob 的数组末尾的段。其中MediaRecorder
.start()
用参数1000
调用,将每个记录的Blob
设置为记录数据的1000ms
。
方法使用 https://github.com/samdutton/simpl/tree/gh-pages/mediarecorder 的修改版本。添加了<input type="number">
元素以设置从录制的视频中删除1s
的块,以便使用.slice()
进行播放和下载
<video id="gum" autoplay muted controls></video>
<video id="recorded" autoplay controls></video>
<div>
<button id="record">Start Recording</button><label for="record"></label><br>
<span>Seconds of recorded video to play (min 1):</span><input min="1" type="number" disabled />
<button id="play" disabled>Play</button>
<span>Seconds of recorded video to download (min 1):</span><input min="1" type="number" disabled /><button id="download" disabled>Download</button>
</div>
javascript
'use strict';
/* globals MediaRecorder */
// This code is adapted from
// https://rawgit.com/Miguelao/demos/master/mediarecorder.html
'use strict';
/* globals MediaRecorder */
// This code is adapted from
// https://rawgit.com/Miguelao/demos/master/mediarecorder.html
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', handleSourceOpen, false);
var mediaRecorder;
var recordedBlobs;
var sourceBuffer;
var gumVideo = document.querySelector('video#gum');
var recordedVideo = document.querySelector('video#recorded');
var input = document.querySelectorAll("input[type=number]");
recordedVideo.ontimeupdate = function(e)
console.log("recorded video currentTime:", e.target.currentTime)
gumVideo.onprogress = function(e)
// console.log("getUserMedia video currentTime:", e.target.currentTime)
var recordButton = document.querySelector('button#record');
var playButton = document.querySelector('button#play');
var downloadButton = document.querySelector('button#download');
recordButton.onclick = toggleRecording;
playButton.onclick = play;
downloadButton.onclick = download;
var currentTimes = [];
recordButton.nextElementSibling.innerHTML = "recorded video "
+ currentTimes.length
+ "s";
// window.isSecureContext could be used for Chrome
var isSecureOrigin = location.protocol === 'https:' ||
location.host === 'localhost';
if (!isSecureOrigin)
alert('getUserMedia() must be run from a secure origin: HTTPS or localhost.' +
'\n\nChanging protocol to HTTPS');
location.protocol = 'HTTPS';
// Use old-style gUM to avoid requirement to enable the
// Enable experimental Web Platform features flag in Chrome 49
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
var constraints =
audio: true,
video: true
;
navigator.getUserMedia(constraints, successCallback, errorCallback);
function successCallback(stream)
console.log('getUserMedia() got stream: ', stream);
window.stream = stream;
if (window.URL)
gumVideo.src = window.URL.createObjectURL(stream);
else
gumVideo.src = stream;
function errorCallback(error)
console.log('navigator.getUserMedia error: ', error);
// navigator.mediaDevices.getUserMedia(constraints)
// .then(function(stream)
// console.log('getUserMedia() got stream: ', stream);
// window.stream = stream; // make available to browser console
// if (window.URL)
// gumVideo.src = window.URL.createObjectURL(stream);
// else
// gumVideo.src = stream;
//
// ).catch(function(error)
// console.log('navigator.getUserMedia error: ', error);
// );
function handleSourceOpen(event)
console.log('MediaSource opened');
sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vp8"');
console.log('Source buffer: ', sourceBuffer);
function handleDataAvailable(event)
if (event.data && event.data.size > 0)
currentTimes.push(gumVideo.currentTime);
recordedBlobs.push(event.data);
recordButton.nextElementSibling.innerHTML = "recorded video "
+ recordedBlobs.length
+ "s";
function handleStop(event)
console.log('Recorder stopped: ', event);
console.log("recorded times from getUserMedia video:", currentTimes);
function toggleRecording()
if (recordButton.textContent === 'Start Recording')
startRecording();
else
stopRecording();
recordButton.textContent = 'Start Recording';
playButton.disabled = false;
downloadButton.disabled = false;
// The nested try blocks will be simplified when Chrome 47 moves to Stable
function startRecording()
var options =
mimeType: 'video/webm',
bitsPerSecond: 100000
;
recordedBlobs = [];
currentTimes = [];
for (var i = 0; i < input.length; i++)
input[i].setAttribute("max", 1);
input[i].setAttribute("disabled", "disabled");
playButton.disabled = true;
downloadButton.disabled = true;
try
mediaRecorder = new MediaRecorder(window.stream, options);
catch (e0)
console.log('Unable to create MediaRecorder with options Object: ', e0);
try
options =
mimeType: 'video/webm,codecs=vp9',
bitsPerSecond: 100000
;
mediaRecorder = new MediaRecorder(window.stream, options);
catch (e1)
console.log('Unable to create MediaRecorder with options Object: ', e1);
try
options = 'video/vp8'; // Chrome 47
mediaRecorder = new MediaRecorder(window.stream, options);
catch (e2)
alert('MediaRecorder is not supported by this browser.\n\n' +
'Try Firefox 29 or later, or Chrome 47 or later,'
+ ' with Enable experimental Web Platform features enabled '
+ ' from chrome://flags.');
console.error('Exception while creating MediaRecorder:', e2);
return;
console.log('Created MediaRecorder', mediaRecorder, 'with options', options);
recordButton.textContent = 'Stop Recording';
playButton.disabled = true;
downloadButton.disabled = true;
mediaRecorder.onstop = handleStop;
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(1000); // collect 1000ms of data
console.log('MediaRecorder started', mediaRecorder);
function stopRecording()
mediaRecorder.stop();
for (var i = 0; i < input.length; i++)
input[i].setAttribute("max", recordedBlobs.length);
input[i].removeAttribute("disabled");
console.log('Recorded Blobs: ', recordedBlobs);
recordedVideo.controls = true;
function play()
console.log(`playing $input[0].values of getUserMedia video`
+ `recorded by MediaRecorder from time ranges`
, currentTimes.slice(0, input[0].value));
// slice `input[0].value` amount, in seconds, from end of recorded video
// for playback
var file = recordedBlobs.slice(0, input[0].value);
var superBuffer = new Blob(file,
type: 'video/webm'
);
recordedVideo.src = window.URL.createObjectURL(superBuffer);
function download()
// slice `input[1].value` amount, in seconds, from end of recorded video
// for download
var file = recordedBlobs.slice(0, input[1].value);
var blob = new Blob(file,
type: 'video/webm'
);
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'test.webm';
document.body.appendChild(a);
a.click();
setTimeout(function()
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
, 100);
plnkrhttps://plnkr.co/edit/LxuV5jMX0RZtDxOxT1qa?p=preview
【讨论】:
这是好东西,我的目的是记录流,将 blob 编码为视频,然后操作该视频。我也会让它在用户调整视频长度的同时播放,但这是我最终可能不得不采取的方法。 MediaRecorder 在 safari 上不工作 @UmeshPatadiya 好的。不确定这与问题有什么关系? 因为您使用 MediaRecorder() 在上面的 sn-p 中录制视频。它正在 chrome 和 mozilla 上运行,你能建议一些解决方案吗? @UmeshPatadiya 没试过 Safari。以上是关于如何使用 JavaScript 减少视频的长度? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用适用于 Android 的 OpenCV 减少实时视频序列中的运动效果?
JS判断视频Video的播放暂停结束完成及获取长度事件监听处理