[TikiWiki-commits] [Git][tikiwiki/tiki][master] [FIX] ToolbarFileRecording: wave bars, camera preview, and recording timer not showing up

"Victor Emanouilov \(@kroky\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <69f18e6f357e_3818ecc816852@gitlab-sidekiq-low-urgency-cpu-bound-v2-858657cb67-rlscl.mail>

Victor Emanouilov pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
b8085a1d by Merci Jacob at 2026-04-29T04:35:15+00:00
[FIX] ToolbarFileRecording: wave bars, camera preview, and recording timer not showing up
---
* [FIX] ToolbarFileRecording: wave bars, camera preview, and recording timer not showing up

See merge request tikiwiki/tiki!10019

- - - - -


3 changed files:

- lib/core/Toolbar/ToolbarFileRecording.php
- lib/jquery_tiki/recordrtc.js
- templates/trackerinput/files.tpl


Changes:

=====================================
lib/core/Toolbar/ToolbarFileRecording.php
=====================================
@@ -65,6 +65,10 @@ class ToolbarFileRecording extends ToolbarUtilityItem
                 <label class="form-check-label" for="recordCamera">Camera</label>
             </div>
         </div>
+        <span class="recording-timer" id="recording-timer-$this->domElementId">00:00</span>
+        <div id="waveform-canvas-$this->domElementId" class="waveform-container">
+            <canvas id="wave-canvas-$this->domElementId" class="w-100 h-100"></canvas>
+        </div>
         HTML;
     }
 


=====================================
lib/jquery_tiki/recordrtc.js
=====================================
@@ -26,8 +26,8 @@ let recordingTimerInterval;
 let videoPreviewElements = {};
 
 
-function createVideoPreview(stream, fieldId) {
-    const containerId = `video-preview-${fieldId}`;
+function createVideoPreview(stream) {
+    const containerId = `video-preview-${recordingInstance.id}`;
     let container = document.getElementById(containerId);
 
     if (!container) {
@@ -35,14 +35,14 @@ function createVideoPreview(stream, fieldId) {
         container.id = containerId;
         container.className = 'video-preview-container';
 
-        const waveformCanvas = document.getElementById(`waveform-canvas-${fieldId}`);
+        const waveformCanvas = document.getElementById(`waveform-canvas-${recordingInstance.id}`);
         if (waveformCanvas && waveformCanvas.parentElement) {
             waveformCanvas.parentElement.insertBefore(container, waveformCanvas);
         }
     }
 
     const video = document.createElement('video');
-    video.id = `live-video-${fieldId}`;
+    video.id = `live-video-${recordingInstance.id}`;
     video.autoplay = true;
     video.muted = true;
     video.playsInline = true;
@@ -52,11 +52,11 @@ function createVideoPreview(stream, fieldId) {
     container.appendChild(video);
     container.style.display = 'block';
 
-    videoPreviewElements[fieldId] = { container, video };
+    videoPreviewElements[recordingInstance.id] = { container, video };
 }
 
-function removeVideoPreview(fieldId) {
-    const preview = videoPreviewElements[fieldId];
+function removeVideoPreview() {
+    const preview = videoPreviewElements[recordingInstance.id];
     if (preview) {
         if (preview.video && preview.video.srcObject) {
             preview.video.srcObject.getTracks().forEach(track => track.stop());
@@ -66,13 +66,15 @@ function removeVideoPreview(fieldId) {
             preview.container.style.display = 'none';
             preview.container.innerHTML = '';
         }
-        delete videoPreviewElements[fieldId];
+        delete videoPreviewElements[recordingInstance.id];
     }
 }
 
-function createWaveBars(stream, fieldId) {
-    const container = document.getElementById(`waveform-canvas-${fieldId}`);
-    const canvas = document.getElementById(`wave-canvas-${fieldId}`);
+function createWaveBars(stream) {
+    const id = recordingInstance.id;
+
+    const container = document.getElementById(`waveform-canvas-${id}`);
+    const canvas = document.getElementById(`wave-canvas-${id}`);
 
     if (!container || !canvas) return;
 
@@ -90,11 +92,11 @@ function createWaveBars(stream, fieldId) {
 
     source.connect(analyser);
 
-    audioContexts[fieldId] = audioContext;
-    analysers[fieldId] = analyser;
+    audioContexts[id] = audioContext;
+    analysers[id] = analyser;
 
     function draw() {
-        animationIds[fieldId] = requestAnimationFrame(draw);
+        animationIds[id] = requestAnimationFrame(draw);
         analyser.getByteFrequencyData(dataArray);
 
         ctx.fillStyle = '#f8f9fa';
@@ -128,18 +130,22 @@ function startRecordingTimer() {
 }
 
 
-function removeWaveBars(fieldId) {
-    if (animationIds[fieldId]) {
-        cancelAnimationFrame(animationIds[fieldId]);
-        delete animationIds[fieldId];
+function removeWaveBars() {
+    if (animationIds[recordingInstance.id]) {
+        console.log('Stopping animation frame for recording instance', recordingInstance.id);
+        cancelAnimationFrame(animationIds[recordingInstance.id]);
+        delete animationIds[recordingInstance.id];
     }
-    if (audioContexts[fieldId]) {
-        audioContexts[fieldId].close();
-        delete audioContexts[fieldId];
+    if (audioContexts[recordingInstance.id]) {
+        console.log('Closing audio context for recording instance', recordingInstance.id);
+        audioContexts[recordingInstance.id].close();
+        delete audioContexts[recordingInstance.id];
     }
-    delete analysers[fieldId];
+    delete analysers[recordingInstance.id];
+
+    $(`#waveform-canvas-${recordingInstance.id}`).hide();
 
-    removeVideoPreview(fieldId);
+    removeVideoPreview();
 }
 
 
@@ -481,9 +487,6 @@ class RecordBase {
         this.startButton = triggerElement;
         this.stopButton = $(triggerElement).next(".stop-recording")[0];
 
-        const fieldId = $(triggerElement).data('field-id');
-        this.timerElement = $(`.recording-timer[data-field-id="${fieldId}"]`);
-
         this.startButtonHtml = $(triggerElement).html();
         this.uploadingStateHtml = $.BUTTON_LOADER_MARKUP + " " + tr("Uploading...");
 
@@ -491,24 +494,30 @@ class RecordBase {
         this.isTrackerFileRecording = !!$(triggerElement).data('tracker-files');
 
         this.commentAreaId = $(triggerElement).data('area-id');
+        this.trackerFieldId = $(triggerElement).data('field-id');
+
+        this.id = this.isCommentRecording ? this.commentAreaId : this.trackerFieldId;
     }
 
     startTimer() {
         this.recordingStartTime = Date.now();
-        this.timerElement.show();
+
+        const timerElement = $(`#recording-timer-${this.id}`);
+
+        timerElement.show();
 
         this.recordingTimerInterval = setInterval(() => {
             const elapsed = Math.floor((Date.now() - this.recordingStartTime) / 1000);
             const minutes = String(Math.floor(elapsed / 60)).padStart(2, '0');
             const seconds = String(elapsed % 60).padStart(2, '0');
-            this.timerElement.text(`${minutes}:${seconds}`);
+            timerElement.text(`${minutes}:${seconds}`);
         }, 1000);
          $('.btn-close[data-bs-dismiss="modal"]').hide();
     }
 
     stopTimer() {
         clearInterval(this.recordingTimerInterval);
-        this.timerElement.hide().text('00:00');
+        $(`#recording-timer-${this.id}`).hide().text('00:00');
          $('.btn-close[data-bs-dismiss="modal"]').show();
     }
 
@@ -608,8 +617,7 @@ class RecordMicrophone extends RecordBase {
             recorder = RecordRTC(microphone, options);
             recorder.startRecording();
             this.startTimer();
-            const fieldId = $(triggerElement).data('field-id');
-            createWaveBars(microphone, fieldId);
+            createWaveBars(microphone);
 
             $(triggerElement).addClass("d-none").prop('disabled', false);
             $(this.stopButton).removeClass("d-none");
@@ -617,10 +625,8 @@ class RecordMicrophone extends RecordBase {
     }
 
     stopRecording() {
-
-        const fieldId = $(this.startButton).data('field-id');
         microphone.stop();
-        removeWaveBars(fieldId);
+        removeWaveBars();
 
         super.stopRecording();
     }
@@ -637,8 +643,6 @@ class RecordCameraAndAudio extends RecordBase {
         super(triggerElement);
 
         getUserMedia(VIDEO_AND_AUDIO_STREAM_CONSTRAINTS, (camera) => {
-            const fieldId = $(triggerElement).data('field-id');
-
             recorder = RecordRTC(camera, {
                 type: 'video'
             });
@@ -646,9 +650,9 @@ class RecordCameraAndAudio extends RecordBase {
             recorder.startRecording();
             this.startTimer();
 
-            createVideoPreview(camera, fieldId);
+            createVideoPreview(camera);
 
-            createWaveBars(new MediaStream(camera.getAudioTracks()), fieldId);
+            createWaveBars(new MediaStream(camera.getAudioTracks()));
 
             recorder.camera = camera;
 
@@ -658,9 +662,8 @@ class RecordCameraAndAudio extends RecordBase {
     }
 
     stopRecording() {
-        const fieldId = $(this.startButton).data('field-id');
         recorder.camera.stop();
-        removeWaveBars(fieldId);
+        removeWaveBars();
         super.stopRecording();
     }
 }
@@ -705,7 +708,7 @@ class RecordScreenAndMicrophone extends RecordScreen {
         getDisplayMedia(VIDEO_STREAM_CONSTRAINTS, (screen) => {
             getUserMedia(AUDIO_STREAM_CONSTRAINTS, (mic) => {
                 screen.addTrack(mic.getTracks()[0]);
-                createWaveBars(mic, $(this.startButton).data('field-id'));
+                createWaveBars(mic);
 
                 addStreamStopListener(screen, () => {
                     $(this.stopButton).trigger("click");


=====================================
templates/trackerinput/files.tpl
=====================================
@@ -98,7 +98,7 @@
             {/if}
             <button class="btn btn-secondary start-recording" data-tracker-files="true" data-type="{$liveRecord}" data-gallery-id="{$field.galleryId}" data-field-id="{$field.fieldId}">{icon name=$recordIcon} {$recordLabel}</button>
             <button class="btn btn-secondary stop-recording d-none">{icon name="stop"} {tr}Stop recording{/tr}</button>
-            <span class="recording-timer" data-field-id="{$field.fieldId}">00:00</span>
+            <span class="recording-timer" id="recording-timer-{$field.fieldId}">00:00</span>
             <div id="waveform-canvas-{$field.fieldId}" class="waveform-container">
                 <canvas id="wave-canvas-{$field.fieldId}" class="w-100 h-100"></canvas>
             </div>



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b8085a1d9226ba7ced0ba0c288a0aa6c07e99d52

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b8085a1d9226ba7ced0ba0c288a0aa6c07e99d52
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.