@@ -3,6 +3,10 @@ import { Script } from 'playcanvas';
33export class VideoRecorderUI extends Script {
44 initialize ( ) {
55 this . createUI ( ) ;
6+ // Listen to video recording progress events
7+ this . app . on ( 'encode:begin' , this . onEncodeBegin , this ) ;
8+ this . app . on ( 'encode:progress' , this . onEncodeProgress , this ) ;
9+ this . app . on ( 'encode:end' , this . onEncodeEnd , this ) ;
610 }
711
812 createUI ( ) {
@@ -40,8 +44,8 @@ export class VideoRecorderUI extends Script {
4044
4145 const label = document . createElement ( 'label' ) ;
4246 label . textContent = labelText ;
43- label . style . width = '100px' ; // Fixed width for alignment
44- label . style . color = '#fff' ; // Very light grey
47+ label . style . width = '100px' ;
48+ label . style . color = '#fff' ;
4549
4650 const select = document . createElement ( 'select' ) ;
4751 select . style . width = '75px' ;
@@ -101,6 +105,9 @@ export class VideoRecorderUI extends Script {
101105 button . style . width = '100%' ; // Make button same width as rows
102106 button . style . fontSize = 'inherit' ;
103107
108+ // Store the button reference on the instance for later access.
109+ this . recordButton = button ;
110+
104111 button . addEventListener ( 'click' , ( ) => {
105112 const videoRecorder = this . entity . script . videoRecorder ;
106113 if ( videoRecorder . recording ) {
@@ -135,8 +142,56 @@ export class VideoRecorderUI extends Script {
135142 }
136143 } ) ;
137144
145+ // Create a simple progress indicator (could be a div styled as a progress bar)
146+ this . progressBar = document . createElement ( 'div' ) ;
147+ this . progressBar . style . height = '10px' ;
148+ this . progressBar . style . background = '#ccc' ;
149+ this . progressBar . style . width = '0%' ;
150+ this . progressBar . style . transition = 'width 0.2s' ;
151+ container . appendChild ( this . progressBar ) ;
152+
138153 container . appendChild ( optionsContainer ) ;
139154 container . appendChild ( button ) ;
140155 document . body . appendChild ( container ) ;
141156 }
157+
158+ onEncodeBegin ( ) {
159+ // Show the progress bar and disable the Record/Stop button once encoding begins.
160+ this . progressBar . style . display = 'block' ;
161+ this . recordButton . disabled = true ;
162+ }
163+
164+ onEncodeProgress ( progress ) {
165+ // progress is a value between 0 and 1
166+ // Update our progress bar width accordingly.
167+ const percent = Math . min ( Math . max ( progress * 100 , 0 ) , 100 ) ;
168+ this . progressBar . style . width = `${ percent } %` ;
169+ }
170+
171+ onEncodeEnd ( buffer ) {
172+ // Hide the progress bar and re-enable the Record/Stop button once encoding is complete.
173+ this . progressBar . style . display = 'none' ;
174+ this . recordButton . disabled = false ;
175+
176+ // Download the recorded video.
177+ const blob = new Blob ( [ buffer ] , { type : 'video/mp4' } ) ;
178+ this . downloadBlob ( blob ) ;
179+ }
180+
181+ /**
182+ * Download the recorded video.
183+ *
184+ * @param {Blob } blob - The recorded video blob.
185+ * @private
186+ */
187+ downloadBlob ( blob ) {
188+ const url = URL . createObjectURL ( blob ) ;
189+
190+ const a = document . createElement ( 'a' ) ;
191+ a . href = url ;
192+ a . download = 'recording.mp4' ;
193+ a . click ( ) ;
194+
195+ URL . revokeObjectURL ( url ) ;
196+ }
142197}
0 commit comments