0 votes
in SoSci Survey (dt.) by s085605 (110 points)

Wir möchten bei einer Audioaufnahme gerne einen Timer anzeigen, damit die Teilnehmer wissen, wie lange ihre Aufnahme läuft. D.h. der Timer soll mit dem Klick auf START beginnen und bei Klick auf STOP enden. Im Idealfall würde nach dem Klick auf STOP die Aufnahmezeit angezeigt und der Button START verändert sich in z.B. NEUSTART o.ä..

Wir haben bereits mit verschiedenen Code-Elementen aus dem Forum experimentiert, doch es gelingt uns leider nicht, die oben beschriebene Wunschlösung herbeizuführen.

Falls Sie uns helfen können, den Code für die Aufnahme entsprechend anzupassen, würden wir uns sehr freuen. Vielen Dank im Voraus :-)

<!-- Buttons -->
<div style="margin: 2em 0 0.5em">
  <button id="btnStart" type="button" tabindex="50">START</button>
  <button id="btnStop" type="button" tabindex="50">STOP</button>
  <button id="btnNeuStart type="button" tabindex="50">NEUSTART</button>

</div>
<div style="margin: 0.5em 0" id="audioReload">Bitte laden Sie die Seite neu (<a href="javascript:SoSciTools.reloadPage()">Neu Laden</a>) und gestatten Sie der Seite Zugriff auf Ihr Audio-Gerät.</div>

<!-- Audio recorder from https://github.com/muaz-khan/RecordRTC -->
<script src="../plugins/RecordRTC/RecordRTC.min.js"></script>
<script src="../plugins/RecordRTC/gumadapter.js"></script>


<script type="text/javascript">
<!--
"use strict";

if ((webrtcDetectedVersion === null) || (webrtcDetectedVersion < webrtcMinimumVersion)) {
  alert("Ihr Browser unterstützt diese Aufnahme leider nicht.");
  throw new Error("no audio support");
}

var buttonStart = document.getElementById("btnStart");
var buttonStop = document.getElementById("btnStop");
var buttonNeuStart = document.getElementById("btnNeuStart");
var date0;
var recordRTC;

function startRecording(button) {
  if (recordRTC) {
    recordRTC.startRecording();
    buttonStart.disabled = true;
    buttonStop.disabled = false;
    buttonNeuStart.disabled = true;
  }
  // Timer
  date0 = new Date();
  window.setInterval(updateCountdown, 1000);
  updateCountdown();
}

function stopRecording(button) {
  if (recordRTC) {
    recordRTC.stopRecording(onStop);
    // You may want to change this to allow a new try (replacing the old one)
    buttonStart.disabled = true;
    buttonStop.disabled = true;
    buttonNeuStart.disabled = false;
  }
}

function onStop(audioURL) {
    var recordedBlob = recordRTC.getBlob();
    // Transfer the data
    %q.id%.sendBLOB(recordedBlob);
}

function onStream(stream) {
    var options = {
        mimeType: "audio/ogg",
        audioBitsPerSecond: 128000
    };
    recordRTC = new RecordRTC(stream, options);
    // Enable the start button
    buttonStart.disabled = false;
    buttonNeuStart.disabled = true;
    // Remove warning
    document.getElementById("audioReload").style.display = "none";
}

function init() {
    buttonStart.disabled = true;
    buttonStop.disabled = true;

    var mediaConstraints = {
        video: false,
        audio: true
    };

    function onError(error) {
      alert("Ihr Computer oder Ihr Browser unterstützt derzeit keine Tonaufnahme." + "\n\n" + error);
    }
    navigator.mediaDevices.getUserMedia(mediaConstraints).then(onStream).catch(onError);
};

SoSciTools.attachEvent(window, "load", init);
SoSciTools.attachEvent(buttonStart, "click", startRecording);
SoSciTools.attachEvent(buttonStop, "click", stopRecording);
SoSciTools.attachEvent(buttonNeuStart, "click", startRecording);

function updateCountdown() {
  // Zeit berechnen
  var date = new Date();
  var time = Math.ceil((date0.getTime() - date.getTime()) / 1000);  // Zeit seit date0 in Sekunden
  // Zeit anzeigen
  var out = document.getElementById("remain");
  if (!out) {
    return;
  }
  while (out.lastChild) {
    out.removeChild(out.lastChild);
  }
  var minutes = Math.floor(time / 60);
  var seconds = String(time - 60 * minutes);
  if (seconds.length < 2) seconds = "0" + seconds;
  var display = String(minutes) + ":" + seconds;
  var displayNode = document.createTextNode(display);
  out.appendChild(displayNode);
}
// -->
</script>
by SoSci Survey (308k points)
Posten Sie doch bitte einmal einen Pretest-Link direkt zur betroffenen Seite ... die Elemente, die Sie verwendet haben, sehen schon recht sinnvoll aus. Aber die Fehlersuche ist wesentlich einfacher, wenn man die Fehlermeldungen in der Browser-Konsole ansehen kann.
by s085605 (110 points)
Natürlich, tut mir leid, dass wir das nicht gleich mit gepostet haben. Hier ist ein Pretest-Link: https://www.soscisurvey.de/spe202110/?act=mNTUOElvNnMcEhvPuXvzi5xk

Danke für die Unterstützung!
by SoSci Survey (308k points)
Doe Browserkonsole meldet:

> No element specified for SoSciTools.attachEvent()

Sie bezieht sich dabei auf folgende Zeile:

SoSciTools.attachEvent(buttonNeuStart, "click", startRecording);

Die entsprechende Variable wird hier definiert:

var buttonNeuStart = document.getElementById("btnNeuStart");

Und das passt scheinbar zu diesem HTML-Element:

<button id="btnNeuStart type="button" tabindex="50">NEUSTART</button>

Warum klappt es trotzdem nicht? Weil da bei genauem Hinsehen ein Anführungszeichen nach der HTML-ID fehlt. Bitte ergänzen Sie dies einmal, dann kann ich weiter suchen.
by s085605 (110 points)
Danke für den genauen Blick! Wie immer steckt der Teufel im Detail... wir haben das fehlende " ergänzt. Nun funktioniert schon mal die Abfolge der Buttons :)
by SoSci Survey (308k points)
Und es zählt nach dem "Start" auch ein Countdown. Nur zeigt der im Moment noch negative Zahlen. Für das Vorzeichen ist wahrscheinlich diese Zeile verantwortlich:

(date0.getTime() - date.getTime())

Denn die aktuelle Zeit (der zweite Parameter) ist das größer als die Startzeit. Dass es dann bei -2:00 losgeht und später springt, hängt wohl damit zusammen, dass die Formatierung in Min. und Sek. nicht auf negative Zahlen ausgelegt ist.
by s085605 (110 points)
Ah, ok verstehe. Ich habe den Code an der Stelle immer falsch gelesen. Mir war nicht klar, dass date.getTime() die aktuelle Zeit ist. Ich habe gerade die beiden Parameter getauscht, dann stimmt es und d die Zeit "läuft nach oben" :)

Jetzt ist nur noch das Problem, dass die Zeit beim Klick auf STOP einfach weiterläuft. Bei Klick auf NEUSTART findet ein Reset statt und es geht wieder bei 0:00 los, aber auch dann führt ein Klick auf STOP nicht zum Anhalten der Zeitanzeige.

Wahrscheinlich muss man hier

function stopRecording(button) {
  if (recordRTC) {
    recordRTC.stopRecording(onStop);
    // You may want to change this to allow a new try (replacing the old one)
    buttonStart.disabled = true;
    buttonStop.disabled = true;
  }
}

definieren, dass der Timer anhält? Ich habe es mit
    updateCountdown.disabled = true;

also
function stopRecording(button) {
  if (recordRTC) {
    recordRTC.stopRecording(onStop);
    // You may want to change this to allow a new try (replacing the old one)
    buttonStart.disabled = true;
    buttonStop.disabled = true;
    updateCountdown.disabled = true;
  }
}

versucht, aber das funktioniert nicht. updateCountdown ist ja auch kein Button... haben Sie eine Idee, wie das funktionieren könnte? Vielen Dank auf jeden Fall schon mal für die tolle Unterstützung bis hierher!

1 Answer

0 votes
by SoSci Survey (308k points)

Jetzt ist nur noch das Problem, dass die Zeit beim Klick auf STOP einfach weiterläuft.

Um das zu unterbinden, müssten Sie das Intervall stoppen. Dafür müssten Sie es aber erstmal in eine Variable speichern. An dieser Stelle:

window.setInterval(updateCountdown, 1000);

Definieren Sie außerhalb der Funktionen eine Variable:

var updateInterval;

Und ergänzen Sie die obige Zeile wie folgt:

updateInterval = window.setInterval(updateCountdown, 1000);

Dann können Sie das beim Stop stoppen:

window.clearInterval(updateInterval);

Alternativ können Sie das Element ausblenden, welches den Timer anzeigt, also...

var out = document.getElementById("remain");
out.style.display = "none";
by s085605 (110 points)
Das ist ja fantastisch! Nun funktioniert alles perfekt :-)

Herzlichen Dank für die großartige Unterstützung!



Hier ist der vollständige Code, falls jemand eine ähnliche Anforderung hat:

<!-- Buttons -->
<div style="margin: 2em 0 0.5em">
  <button id="btnStart" type="button" tabindex="50">START</button>
  <button id="btnStop" type="button" tabindex="50">STOP</button>
  <button id="btnNeuStart" type="button" tabindex="50">NEUSTART</button>

</div>
<div style="margin: 0.5em 0" id="audioReload">Bitte laden Sie die Seite neu (<a href="javascript:SoSciTools.reloadPage()">Neu Laden</a>) und gestatten Sie der Seite Zugriff auf Ihr Audio-Gerät.</div>

<!-- Audio recorder from https://github.com/muaz-khan/RecordRTC -->
<script src="../plugins/RecordRTC/RecordRTC.min.js"></script>
<script src="../plugins/RecordRTC/gumadapter.js"></script>


<script type="text/javascript">
<!--
"use strict";

if ((webrtcDetectedVersion === null) || (webrtcDetectedVersion < webrtcMinimumVersion)) {
  alert("Ihr Browser unterstützt diese Aufnahme leider nicht.");
  throw new Error("no audio support");
}

var buttonStart = document.getElementById("btnStart");
var buttonStop = document.getElementById("btnStop");
var buttonNeuStart = document.getElementById("btnNeuStart");
var date0;
var recordRTC;
var updateInterval;

function startRecording(button) {
  if (recordRTC) {
    recordRTC.startRecording();
    buttonStart.disabled = true;
    buttonStop.disabled = false;
    buttonNeuStart.disabled = true;
  }
  // Timer
  date0 = new Date();
  updateInterval = window.setInterval(updateCountdown, 1000);
  updateCountdown();
}

function stopRecording(button) {
  if (recordRTC) {
    recordRTC.stopRecording(onStop);
    // You may want to change this to allow a new try (replacing the old one)
    buttonStart.disabled = true;
    buttonStop.disabled = true;
    buttonNeuStart.disabled = false;
    window.clearInterval(updateInterval);
  }
}

function onStop(audioURL) {
    var recordedBlob = recordRTC.getBlob();
    // Transfer the data
    %q.id%.sendBLOB(recordedBlob);
}

function onStream(stream) {
    var options = {
        mimeType: "audio/ogg",
        audioBitsPerSecond: 128000
    };
    recordRTC = new RecordRTC(stream, options);
    // Enable the start button
    buttonStart.disabled = false;
    buttonNeuStart.disabled = true;
    // Remove warning
    document.getElementById("audioReload").style.display = "none";
}

function init() {
    buttonStart.disabled = true;
    buttonStop.disabled = true;

    var mediaConstraints = {
        video: false,
        audio: true
    };

    function onError(error) {
      alert("Ihr Computer oder Ihr Browser unterstützt derzeit keine Tonaufnahme." + "\n\n" + error);
    }
    navigator.mediaDevices.getUserMedia(mediaConstraints).then(onStream).catch(onError);
};

SoSciTools.attachEvent(window, "load", init);
SoSciTools.attachEvent(buttonStart, "click", startRecording);
SoSciTools.attachEvent(buttonStop, "click", stopRecording);
SoSciTools.attachEvent(buttonNeuStart, "click", startRecording);

function updateCountdown() {
  // Zeit berechnen
  var date = new Date();
  var time = Math.ceil((date.getTime() - date0.getTime()) / 1000);  // Zeit seit date0 in Sekunden
  // Zeit anzeigen
  var out = document.getElementById("remain");
  if (!out) {
    return;
  }
  while (out.lastChild) {
    out.removeChild(out.lastChild);
  }
  var minutes = Math.floor(time / 60);
  var seconds = String(time - 60 * minutes);
  if (seconds.length < 2) seconds = "0" + seconds;
  var display = String(minutes) + ":" + seconds;
  var displayNode = document.createTextNode(display);
  out.appendChild(displayNode);
}
// -->
</script>

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...