1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * Class implement the video frame recorder extension client.
12 /** @suppress {duplicate} */
13 var remoting
= remoting
|| {};
17 * @param {remoting.ClientPlugin} plugin
19 remoting
.VideoFrameRecorder = function(plugin
) {
20 this.fileWriter_
= null;
21 this.isRecording_
= false;
22 this.plugin_
= plugin
;
26 * Starts or stops video recording.
28 remoting
.VideoFrameRecorder
.prototype.startStopRecording = function() {
30 if (this.isRecording_
) {
31 this.isRecording_
= false;
32 data
= { type
: 'stop' }
34 chrome
.fileSystem
.chooseEntry(
35 {type
: 'saveFile', suggestedName
: 'videoRecording.pb'},
36 this.onFileChosen_
.bind(this));
38 this.isRecording_
= true;
39 data
= { type
: 'start' }
41 this.plugin_
.sendClientMessage('video-recorder', JSON
.stringify(data
));
45 * Returns true if the session is currently being recorded.
48 remoting
.VideoFrameRecorder
.prototype.isRecording = function() {
49 return this.isRecording_
;
53 * Handles 'video-recorder' extension messages and returns true. Returns
54 * false for all other message types.
55 * @param {string} type Type of extension message.
56 * @param {string} data Content of the extension message.
59 remoting
.VideoFrameRecorder
.prototype.handleMessage
=
60 function(type
, data
) {
61 if (type
!= 'video-recorder') {
65 var message
= getJsonObjectFromString(data
);
66 var messageType
= getStringAttr(message
, 'type');
67 var messageData
= getStringAttr(message
, 'data');
69 if (messageType
== 'next-frame-reply') {
70 if (!this.fileWriter_
) {
71 console
.log("Received frame but have no writer");
75 console
.log("Finished receiving frames");
76 this.fileWriter_
= null;
80 console
.log("Received frame");
81 /* jscompile gets confused if you refer to this as just atob(). */
82 var videoPacketString
= /** @type {string?} */ window
.atob(messageData
);
84 console
.log("Converted from Base64 - length:" + videoPacketString
.length
);
87 for (var offset
= 0; offset
< videoPacketString
.length
; offset
+= 512) {
88 var slice
= videoPacketString
.slice(offset
, offset
+ 512);
89 var byteNumbers
= new Array(slice
.length
);
90 for (var i
= 0; i
< slice
.length
; i
++) {
91 byteNumbers
[i
] = slice
.charCodeAt(i
);
93 var byteArray
= new Uint8Array(byteNumbers
);
94 byteArrays
.push(byteArray
);
97 console
.log("Writing frame");
98 videoPacketString
= null;
100 * Our current compiler toolchain only understands the old (deprecated)
101 * Blob constructor, which does not accept any parameters.
102 * TODO(wez): Remove this when compiler is updated (see crbug.com/405298).
103 * @suppress {checkTypes}
104 * @param {Array} parts
107 var makeBlob = function(parts
) {
108 return new Blob(parts
);
110 var videoPacketBlob
= makeBlob(byteArrays
);
113 this.fileWriter_
.write(videoPacketBlob
);
118 console
.log("Unrecognized message: " + messageType
);
122 /** @param {FileEntry} fileEntry */
123 remoting
.VideoFrameRecorder
.prototype.onFileChosen_ = function(fileEntry
) {
125 console
.log("Cancelled save of video frames.");
127 /** @type {function(string):void} */
128 chrome
.fileSystem
.getDisplayPath(fileEntry
, function(path
) {
129 console
.log("Saving video frames to:" + path
);
131 fileEntry
.createWriter(this.onFileWriter_
.bind(this));
135 /** @param {FileWriter} fileWriter */
136 remoting
.VideoFrameRecorder
.prototype.onFileWriter_ = function(fileWriter
) {
137 console
.log("Obtained FileWriter for video frame write");
138 fileWriter
.onwriteend
= this.onWriteComplete_
.bind(this);
139 this.fileWriter_
= fileWriter
;
140 this.fetchNextFrame_();
143 remoting
.VideoFrameRecorder
.prototype.onWriteComplete_ = function(e
) {
144 console
.log("Video frame write complete");
145 this.fetchNextFrame_();
148 remoting
.VideoFrameRecorder
.prototype.fetchNextFrame_ = function() {
149 console
.log("Request next video frame");
150 var data
= { type
: 'next-frame' }
151 this.plugin_
.sendClientMessage('video-recorder', JSON
.stringify(data
));