問題描述
基于
所以看起來它以某種方式無法正確錄制,因為文件是空的..
edit 調試時我發現記錄可能正常工作,因為我控制臺日志的 blob 在內部具有價值,在 toArrayBuffer
之后,我的 blob 內部不再具有價值.
代碼是:
(function () {'使用嚴格';var fs = 需要('fs');var { desktopCapturer } = 要求('電子');var 記錄器,blob = [];有角度的.module('app').controller('loggedScreen', 控制器);Controller.$inject = ['$scope'];功能控制器($范圍){var startRecord = 函數 () {console.log('開始');desktopCapturer.getSources({types: ['window', 'screen']}, function(error) {if (error) 拋出錯誤;navigator.webkitGetUserMedia({音頻:假,視頻: {強制的: {chromeMediaSource: '桌面',最小寬度:1280,最大寬度:1280,最小高度:720,最大高度:720}}},句柄流,句柄錯誤);返回;});};函數句柄錯誤(錯誤){console.log('出了點問題,但不應該');}函數句柄流(流){記錄器 = 新媒體記錄器(流);斑點 = [];recorder.ondataavailable = 函數(事件){blobs.push(event.data);};記錄器.start();}函數 toArrayBuffer(blob, cb) {var fileReader = new FileReader();fileReader.onload = 函數() {var arrayBuffer = this.result;cb(數組緩沖區);};fileReader.readAsArrayBuffer(blob);}函數 toBuffer(ab) {var buffer = new Buffer(ab.byteLength);var arr = new Uint8Array(ab);for (var i = 0; i < arr.byteLength; i++) {緩沖區[i] = arr[i];}返回緩沖區;}功能停止記錄(){記錄器.stop();console.log(blob);//300k 字節toArrayBuffer(new Blob(blob, {type: 'video/webm'}), function(ab) {控制臺.log(ab);//0 字節var 緩沖區 = toBuffer(ab);var 文件 = `./videos/example.webm`;fs.writeFile(文件,緩沖區,函數(錯誤){如果(錯誤){console.error('保存視頻失敗' + err);} 別的 {console.log('保存的視頻:' + 文件);}});});}開始記錄();設置超時(函數(){//7秒后停止錄制停止錄制();}, 7000);}})();
startRecord()
函數會立即執行,它也 console.log
在點擊此控制器后按預期啟動.
stopRecording()
函數在 7 秒后正確執行,它 console.log('Saved video: ' + file);
就好了.
然后我轉到我剛剛創建的視頻文件夾,打開我保存的 example.webm 文件,它是空的.
它不會在控制臺中打印任何錯誤.
<小時>- 我在
stopRecording()
函數中停止記錄器后consoled.log(blob)
看看它是否真的是 Blob. - 我在
toArrayBuffer(new Blob(blob, {type: 'video/webm'}), function(ab) {}) 內的
console.log(ab)
回調.
當 ab
不包含值時,我的行為是 blob
包含值.
我自己真的解決不了,尋找答案我創建了demo repository 復制最少的示例,只需克隆它以查看您自己的行為
您的 recorder.stop()
將按如下方式運行:(來自 MediaRecorder 文檔)
當調用 stop() 方法時,UA 將運行以下步驟:
- 如果
MediaRecorder.state
為非活動",則引發 DOMInvalidState
錯誤并終止這些步驟.如果MediaRecorder.state
不是非活動",則繼續下一步. - 將
MediaRecorder.state
設置為非活動"并停止捕獲媒體. - 引發一個
dataavailable
事件,其中包含已收集的 Blob 數據. - 引發
stop
事件.
在您的情況下,您無需等待 stop
事件,因此 dataavailable
僅在您啟動文件保存方法后才會填充 blob
.
您必須重組 stopRecording
以確保記錄的數據可用.例如:
function stopRecording () {常量保存 = () =>{...}recorder.onstop = 保存記錄器.stop()}
Basing on electron api and this question I'm trying to save recorded user screen to .webm file in videos folder in root app folder.
Actually it's almost working because it save .webm file but the file which is saved is empty, it weigh 0B.. I don't know what I'm missing here.
So it looks like it's somehow not recording correctly because file is empty..
edit when debbuging I discovered that recording is probably working correctly because blobs which I console log has value inside, after toArrayBuffer
my blob no longer has value inside.
Code is:
(function () {
'use strict';
var fs = require('fs');
var { desktopCapturer } = require('electron');
var recorder, blobs = [];
angular
.module('app')
.controller('loggedScreen', Controller);
Controller.$inject = ['$scope'];
function Controller($scope) {
var startRecord = function () {
console.log('started');
desktopCapturer.getSources({types: ['window', 'screen']}, function(error) {
if (error) throw error;
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
minWidth: 1280,
maxWidth: 1280,
minHeight: 720,
maxHeight: 720
}
}
}, handleStream, handleError);
return;
});
};
function handleError(err) {
console.log('something went wrong but it shouldnt');
}
function handleStream(stream) {
recorder = new MediaRecorder(stream);
blobs = [];
recorder.ondataavailable = function (event) {
blobs.push(event.data);
};
recorder.start();
}
function toArrayBuffer(blob, cb) {
var fileReader = new FileReader();
fileReader.onload = function() {
var arrayBuffer = this.result;
cb(arrayBuffer);
};
fileReader.readAsArrayBuffer(blob);
}
function toBuffer(ab) {
var buffer = new Buffer(ab.byteLength);
var arr = new Uint8Array(ab);
for (var i = 0; i < arr.byteLength; i++) {
buffer[i] = arr[i];
}
return buffer;
}
function stopRecording() {
recorder.stop();
console.log(blobs); // 300k bytes
toArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {
console.log(ab); // 0 bytes
var buffer = toBuffer(ab);
var file = `./videos/example.webm`;
fs.writeFile(file, buffer, function(err) {
if (err) {
console.error('Failed to save video ' + err);
} else {
console.log('Saved video: ' + file);
}
});
});
}
startRecord();
setTimeout(function() {
// stop recording after 7sec
stopRecording();
}, 7000);
}
})();
startRecord()
function is executed immediately, it also console.log
started as expected just after hitting this controller.
stopRecording()
function is executed after 7 second correctly, it console.log('Saved video: ' + file);
just fine.
Then I go to my just created videos folder I open my saved example.webm file and it's empty.
It doesn't print any error in console.
- I
consoled.log(blobs)
after stoping recorder instopRecording()
function to see if it's actually Blob. - I
console.log(ab)
insidetoArrayBuffer(new Blob(blobs, {type: 'video/webm'}), function(ab) {})
callback.
I've got behaviour as blobs
contains value when ab
not.
I really can't solve it myself, looking for answer I create demo repository with minimal reproduced example just clone it to see behaviour for your own
Your recorder.stop()
will run as follows: (from MediaRecorder docs)
When the stop() method is invoked, the UA queues a task that runs the following steps:
- If
MediaRecorder.state
is "inactive", raise a DOMInvalidState
error and terminate these steps. If theMediaRecorder.state
is not "inactive", continue on to the next step.- Set the
MediaRecorder.state
to "inactive" and stop capturing media.- Raise a
dataavailable
event containing the Blob of data that has been gathered.- Raise a
stop
event.
In your case you don't wait up the stop
event, so dataavailable
will fill blobs
only after you started the file saving method.
You have to restructure stopRecording
to ensure recorded data is available. For example:
function stopRecording () {
const save = () => {
...
}
recorder.onstop = save
recorder.stop()
}
這篇關于將 desktopCapturer 從 Electron 應用程序保存到視頻文件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!