0 votes
in SoSci Survey (dt.) by s057462 (330 points)

Hallo!
Wir haben das Erfragen der Webcam Erlaubnis via html eingebettet:

<script>
var video = document.querySelector("#videoElement");
if(navigator.mediaDevices.getUserMedia){
    navigator.mediaDevices.getUserMedia({video:true})}n

Jetzt würden wir aber gerne in Abhängigkeit davon, ob der Teilnehmer die Erlaubnis gab oder nicht, unterschiedliches routing im Fragebogen vornehmen. Ist es möglich, das feedback bezüglich der Erlaubnis vom Browser aufzunehmen?

Ich habe das hier probiert, aber die Verknuepfung mit php code wie z.B. goTo ist mir nicht klar:

<script>
var video = document.querySelector("#videoElement");
if(navigator.mediaDevices.getUserMedia){
    navigator.mediaDevices.getUserMedia({video:true})
    if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true })
       .then(function (stream) {
       video.srcObject = stream;
       })
       .catch(function (err0r) {
       goTo('exit');
});

}n

1 Answer

0 votes
by SoSci Survey (327k points)

Jetzt würden wir aber gerne in Abhängigkeit davon, ob der Teilnehmer die Erlaubnis gab oder nicht, unterschiedliches routing im Fragebogen vornehmen.

Es ist nicht ganz trivial ... die Lösung lautet: Promises.

Sehen SIe sich als erstes bitte einmal die JavaScript-Methode
MediaDevices.getUserMedia() an. Diese leifert als Ergebnis ein Promise zurück. Das ist das, weshalb Sie im Code .then() und .catch() verwenden können.

Grob gesprochen können Sie im catch() auf eine Ablehnung der Video-Anfrage reagieren. Und dies können Sie mittels einer internen Variable auch an den Datensatz weitergeben. Sobald Sie es im Datensatz haben, können Sie auf der Folgeseite direkt mittels PHP-Filter darauf reagieren.

by s057462 (330 points)
Okay, das könnten wir hinbekommen.
Eine weitere Frage ist aber jetzt aufgetaucht: wenn die nächste Seite aufgerufen wird, geht die webcam aus, d.h. die Erlaubnis erlischt, was ja auch gut ist, aber in unsere Fall problematisch, weil wir die webcam über die restlichen (40) Seiten des Surveys angeschaltet haben wollten und nicht auf jeder Seite nach Erlaubnis fragen moechten. Gibt es einen Weg, das zu verhindern, damit wie wir die Seiten programmieren? Oder kann die Zulassung der webcam - Info auf weitergegeben werden und vom browser gelesen werden?
Danke schon mal!
by SoSci Survey (327k points)
Wenn Sie einen Prozess über mehrere Seite am Leben erhalten möchten, dann können Sie z.B. mit Frames arbeiten: https://www.soscisurvey.de/help/doku.php/de:create:frameset
by s057462 (330 points)
Okay, wir haben das jetzt so implementiert:
auf der 4. Seite im Survey haben rufen wir ein java script auf:
top.webcam_frame.location.href = "webcam_prompt.html";

die webcam_prompt.html Datei (hoch geladen bei Medien) enthält den code:

<script type="text/javascript">

        //forces prompt for camera use, if denied prompts again
        function permission_prompt() {
            var video = document.getElementById("#video");
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
                    video.srcObject = stream;
                    video.play();
                }).catch(function (err) {
                    if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
                        SoSciTools.submitButtonsHide();
                    }
                })
            }
        }

        permission_prompt();
    </script>


Und die webcam_frame.html Datei (auch in den Medien hochgeladen) enthält:


<head>
    <title>webcam_frame</title>
    <meta charset="utf-8">
</head>
<frameset rows="99%, 1%">
    <frameset src="    https://www.soscisurvey.de/PDG3/" name="staghunt2_game">
        <frame name="webcam_frame">
    </frameset>
</frameset>


Wenn wir den survey mit
https://www.soscisurvey.de/PDG3/webcam_frame.html

aufrufen, zeigt es nur eine leere Seite.
Das Page inspection tool sagt: about:blank (an error occurred trying to load the rescource).

Haben Sie evtl. eine Idee dazu?
Hedwig
by SoSci Survey (327k points)
Meine erste Vermutung ist, dass es an den Leerzeichen im `src`liegt:

    <frameset src="    https://www.soscisurvey.de/PDG3/" name="staghunt2_game">

Meine zweite Vermutung ist, dass Ihre Frame-Konstruktion insgesamt nicht stimmt. Sie haben nur ein Frame definiert, dieses hat aber keine `src`. Das <frameset> hingegen dürfte kein `src` haben.

https://wiki.selfhtml.org/wiki/HTML/Frames
by s057462 (330 points)
Super, das war es!
<frame src="https://www.soscisurvey.de/PDG3/" name="staghunt2_game">
funktioniert und die webcam bleibt (wenn einmal zugestimmt) über mehrere Seiten an!
Danke!
by s057462 (330 points)
Noch mal eine Nachfrage:
Wir haben jetzt einen "wrapper survey" implementiert, um zuerst die Studie zu erklären und im verlinkten survey dann die webcam Abfrage zu verwenden (die auf der ersten Seite des surveys aktiviert wird), leider führt das wieder zu Problemen:
Innerhalb des Projekts haben wir ein Projekt angelegt, das Start_PDGfaces heisst und nach einer Info Seite folgenden Link enthält:
<input type="button" value="I CONSENT" onclick="window.location.href='https://www.soscisurvey.de/PDG3/webcam_prompt.html'" />

Der Survey Hauptlink defaults zu diesem Fragebogen im Projekt: https://www.soscisurvey.de/PDG3/?q=Game

Die erste Seite dieses Fragebogen enthält:
<script type="text/javascript">

top.webcam_frame.location.href = "https://www.soscisurvey.de/PDG3/webcam_prompt.html";

</script>


Und wir verwenden diese webcam_frame.html Datei:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>

<head>
    <title>webcam_frame</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<frameset rows="99%, 1%">
    <frameset src="https://www.soscisurvey.de/PDG3/" name="staghunt2_game">
        <frame name="webcam_frame">
    </frameset>
</frameset>

    <body>
        var button = document.createElement("BUTTON");
        <button.onclick="window.location.href = 'https://"
    </body>
    
</html>



Und diese webcam_prompt.html Datei:
<!DOCTYPE html>

<html>

<head>
    <meta charset="UTF-8">
    <title>webcam_prompt</title>

    <script type="text/javascript">

        //forces prompt for camera use, if denied prompts again
        function permission_prompt() {
            var video = document.getElementById("#video");
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
                    video.srcObject = stream;
                    video.play();
                }).catch(function (err) {
                    if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
                        SoSciTools.submitButtonsHide();
                    }
                })
            }
        }

        permission_prompt();
    </script>
</head>

</html>



Wenn wir den Survey vom Wrapper aus starten ODER diesen Link in den Browser eingeben: https://www.soscisurvey.de/PDG3/webcam_prompt.html
kommt nur eine leere Seit, zwar mit webcam Abfrage aber sonst nichts.


Haben Sie noch mal eine Idee, was falsch sein könnte?

Wenn Wir den Link im Wrapper zu
<input type="button" value="I CONSENT" onclick="window.location.href='https://www.soscisurvey.de/PDG3/?q=Game/webcam_prompt.html'" />

Sendern, kommen wir die Fehlermeldung:
"Questionnaire Error
There is no questionnaire with the name Game/webcam_prompt.html in this survey.”

Danke schon mal!
by SoSci Survey (327k points)
Ich denke, Sie möchten die Teilnehmer nicht zu webcam_prompt.html umleiten, sondern zu webcam_frame.html - könnte das sein?
by s057462 (330 points)
Link mit
'https://www.soscisurvey.de/PDG3/?q=Game/webcam_frame.html'
fuehrt zu:
Questionnaire Error
There is no questionnaire with the name Game/webcam_frame.html in this survey.

Link mit
'https://www.soscisurvey.de/PDG3/webcam_frame.html'
fuehrt zum anderen Survey aber OHNE webcam prompt?
by SoSci Survey (327k points)
Soweit ich sehe, ist die webcame_frame.html noch nicht ganz korrekt. Und zwar heißt es dort:

<frame name="webcam_frame">

Aber Sie möchten offenbar auch gleich noch einen Inhalt laden ... das müssten Sie entweder per JavaScript im Fragebogen machen oder mittels

<frame name="webcam_frame" src="https://www.soscisurvey.de/PDG3/webcam_prompt.html">

Danach darf übrigens nur ein </frameset> folgend und auch der <body> muss (komplett) raus.
by s057462 (330 points)
Okay, I made those changes in the webcam_frame.html
file, but it is still giving the same error?
by SoSci Survey (327k points)
Now, you load the prompt.html in both Frames. The larger one should load the questionnaire (without webcam_prompt.html), the other one should be fine.
by s057462 (330 points)
I don't really know which parts you mean?
by SoSci Survey (327k points)
Here is what I think the frameset should look like:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
    <title>Survey on Whatever</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<frameset rows="99%, 1%">
    <frame src="https://www.soscisurvey.de/PDG3/" name="questionnaire">
    <frame src="https://www.soscisurvey.de/PDG3/webcam_prompt.html" name="staghunt2_game">
</frameset>
</html>

It hase two frames (<frame>), one contains the questionnaire, the other one is for the webcam. I cannot tell you if the webcam stuff works, but the frameset should.
by s057462 (330 points)
YES! Danke, das war es, danke!
by s057462 (330 points)
Noch eine nachfolgende Frage:
Wie genau können wir die Reaktion als interne variable speichern?

Wir haben das in der prompt Datei so eingebaut aber das scheint noch nicht zu funktionieren:
<!DOCTYPE html>

<html>

<head>
    <meta charset="UTF-8">
    <title>webcam_prompt</title>

    <script type="text/javascript">

        //forces prompt for camera use, if denied prompts again
        function permission_prompt() {
            var video = document.getElementById("#video");
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
                    video.srcObject = stream;
                    video.play();
                }).catch(function (err) {
                    if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
                        SoSciTools.submitButtonsHide();
                        var input = document.getElementById("IV04_01");
                        input.value = 0;
                    }
                })
            }
        }

        permission_prompt();
    </script>
</head>

</html>
by SoSci Survey (327k points)
Sie schreiben u.a.

var input = document.getElementById("IV04_01");

Öffnen Sie doch bitte mal die JavaScript-Fehlerkonsole im Browser. Dann können sie genau nachverfolgen was funktioniert und was nicht. Für die o.g. Zeile (und natürlich sollten Sie auch unter video.play() so eine Zeile einfügen) werden Sie eine Fehlermeldung bekommen, dass NULL oder "undefined" kein value-Attribut hat. Das liegt daran, weil Sie mit 2 getrennten Frames - und damit mit 2 Dokumenten arbeiten. Und das IV04_01 kommt in dem Dokument mit dem Video nunmal nicht vor.

Das heißt, Sie müssen erst einmal das andere Frame adressieren. Dazu gibt es eiieg Anleitungen im Netz, z.B. https://weblog.west-wind.com/posts/2009/Jan/06/Accessing-Html-Document-Content-in-other-Frames - im anderen Frame haben Sie dann wieder ein document, in welchem Sie das getElementById() verwenden können.

Ich will Ihnen nichts vormachen: Da liegt noch ein Stück Arbeit vor Ihnen. Aber mit der Fehlerkonsole und ein wenig trial and error lässt sich das meistern. Und für spezifische Fragen gibt es ja noch den Online-Support hier.
by s057462 (330 points)
We finally got the chance to continue working on this.
The current code looks like:

<script type="text/javascript">
        //forces prompt for camera use, if denied prompts again
        function permission_prompt() {
            var video = document.getElementById("#video");
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                navigator.mediaDevices.getUserMedia({
                    video: true
                }).then(function(stream) {
                    video.srcObject = stream;
                    video.play();
                    var input = document.getElementById("IV12_01");
                    input.value = 1;
                }).catch(function(err) {
                    if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
                        var input = document.getElementById("IV12_01");
                        input.value = 2;
                        SoSciTools.buttonHide();
                    }
                })
            }
        }

        permission_prompt();

    </script>

We now get after rejecting the webcam (should loop into the error frame) no buttonhide and the console says:
Unhandled Promise Rejection: Type Error: Null is not an object (evaluating 'input.value = 2')

Danke für einen Hinweis was wir hier noch falsch machen.
by SoSci Survey (327k points)
In dem catch()-Teil, welcher die Ablehnung behandelt, tritt ein Fehler auf. Und zwar in folgenden Zeilen:

var input = document.getElementById("IV12_01");
input.value = 2;

Die Fehlermeldung "Null is not an object" bezieht sich darauf, dass die Variable  input offenbar NULL ist. Heißt, dass kein HTML-Element mit der Kennung (ID)( IV12_01 gefunden wurde. Das wiederum könnte daran liegen, dass Sie die interne Variable IV12 entweder gar nicht auf die Seite gezogen haben oder dass Sie nicht über dem JavaScript-Code steht.
by s057462 (330 points)
Wir hatten die Variable IV12_01 tatsächlich noch nicht auf der Seite, ich habe sie aber jetzt hinzugefügt und über dem javascript element platziert, aber bekomme immer noch dieselbe Fehlermeldung?
by SoSci Survey (327k points)
Könnten Sie wohl bitte einen Pretest-Link direkt (!) zur betroffenen Seite posten? Dann kann ich gerne einen Blick darauf werfen.
by s057462 (330 points)
Gern, man muss den folgenden Link verwenden, um dann das routing zu der neuen "frame" Seite zu benutzen:
https://www.soscisurvey.de/PDG3/?q=Start

die Frage nach der webcam kommt nach der [I consent] Seite.

oder direkt diesen Link:
https://www.soscisurvey.de/PDG3/webcam_frame.html
by SoSci Survey (327k points)
Da bekomme ich zunächst die Meldung

top.webcam_frame is undefined

Vermutlich deshalb, weil das Frame "webcam_prompt" heißt. Weiter komme ich dann aber auch nicht, weil die Frames leer sind?!
by s057462 (330 points)
Okay, den Fehler sehe ich auch, kann ich aber nicht zuordnen, die webcam Abfrage kommt bei mir, bei Ihnen nicht?
by SoSci Survey (327k points)
Nein, nicht, wenn ich mit Firefox über einen der oben genannten Links den Fragebogen aufrufe.
by s057462 (330 points)
Seltsam, ich habe es in Safari probiert und jetzt in Firefox und bekomme die webcam Abfrage.
Woran koennte das liegen?
Und: was könnte TypeError: undefined is not an object (das ist der andere Fehler) bedeuten?

Auf der Seite des Surveys, zu dem verlinkt wird und der mit verschiedenen frames starte (wegen der laufenden webcam) haben wir dieses java script:
<script type="text/javascript">

top.webcam_frame.location.href = "https://www.soscisurvey.de/PDG3/webcam_prompt.html";

</script>

und darüber ist die IV12_01 eingebettet.
by SoSci Survey (327k points)
Beim aufruf der webcam_frame.html bekomme ich nun das Prompt. Aber beginnen wir mal ganz klein. Die webcam_frame.html hat folgenden Inhalt:

<frameset rows="99%, 1%">
        <frame src="https://www.soscisurvey.de/PDG3/" name="survey">
        <frame src="https://www.soscisurvey.de/PDG3/webcam_prompt.html" name="webcam_prompt">
</frameset>

Der Survey startet mit einer leeren Seite (nicht sehr kleidsam aber nicht falsch) und die webcam_prompt.html enthält folgende Zeile:

var input = document.getElementById("IV12_01");

Nun gibt es in der webcam_prompt.html aber KEIN Element mit der ID IV12_01.  Dieses ist im anderen Frame. Erstmal müssen Sie also auf das andere Frame und dessen document zugreifen, damit Sie zum Eingabefeld kommen (https://weblog.west-wind.com/posts/2009/Jan/06/Accessing-Html-Document-Content-in-other-Frames).

Und dann haben Sie im Fragebogen noch folgende Zeile:

top.webcam_frame.location.href = "https://www.soscisurvey.de/PDG3/webcam_prompt.html";

Zugleich haben Sie im Frameset (s.o.) aber kein Frame mit dem Namen webcam_frame definiert, sondern nur "survey" und "webcam_prompt".
by s057462 (330 points)
Okay, ich habe jetzt in der webcam_frame folgendes eingefügt, um IV12_01 im anderen frame aufrufen zu können:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>

<head>
    <title>Survey</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<frameset rows="99%, 1%">
    <frame src="https://www.soscisurvey.de/PDG3/" name="survey">
</frame>        
   <script type="text/javascript">
       window.onload = function() {
           var frame = document.getElementById("IV12_01");
       };    
        <frame src="https://www.soscisurvey.de/PDG3/webcam_prompt.html" name="webcam_prompt">
</frameset>

</html>


Und in webcam_prompt:
<!DOCTYPE html>

<html>

<head>
    <meta charset="UTF-8">
    <title>webcam_prompt</title>

    <script type="text/javascript">
        //forces prompt for camera use, if denied prompts again
        function permission_prompt() {
            var video = document.getElementById("#video");
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                navigator.mediaDevices.getUserMedia({
                    video: true
                }).then(function(stream) {
                    video.srcObject = stream;
                    video.play();
                    var input = window.parent.document.getElementById("IV12_01");
                    input.value = 1;
                }).catch(function(err) {
                    if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
                        var input = window.parent.document.getElementById("IV12_01");
                        input.value = 2;
                        SoSciTools.buttonHide();
                    }
                })
            }
        }

        permission_prompt();

    </script>
</head>

</html>


(den doppelten webcam-Aufruf von Seite 1 habe ich auskommentiert und auch ein bisschen text auf die erste Seite gepackt.

Die Fehlermeldung ist immer noch die gleiche, aber ich kann nicht herausfinden, wie ich ein "Element mit der ID IV12_01" einfügen kann?
by SoSci Survey (327k points)
Ich denke nicht, dass das Script im Frameset sinnvoll ist bzw. einen Zweck erfüllt. In dem verlinkten Blog ging es ja um ein iFrame, das vom Eltern-Element aus angesprochen werden sollte. Entsprechend auch nicht diese Zeile:

window.parent.document.getElementById("IV12_01");

Es müsste wohl eher heißen (vgl. der Link aus meiner letzten Nachricht):

var surveyFrame = window.parent.getElementById("survey");
var input = surveyDoc.contentDocument.getElementById("IV12_01");

Dafür müssten Sie im Frameset neben name="survey" auch noch id="survey" notieren. Und prüfen Sie bitte mittels console.log(surveyFrame), ob Sie das Frame damit korrekt ansprechen.
by s057462 (330 points)
Hallo Herr Leiner,
wit haben verschiedene Dinge versucht, aber der Haken scheint immer noch zu sein, die Interne Variable IV04_01 abzurufen, auch wenn wir den Abruf auf die nächste Seite verschieben (wir dachten dass die IV eventuell noch nicht verfügbar ist) und obwohl, die IV korrekt im Datensatz abgelegt wird.
Wir bekommen diese Fehlermeldung:
There is an error in the PHP code:
Questionnaire Error: The PHP variable $IV04_01 has been used but the variable is yet undefined (the variable has no value).

001 namespace s2survey\questionnaire\environment;
002
003 option('nextbutton', false);
004 if($IV04_01 == 2){
005     return 'go:GB'; }
006 else{ return 'go:Demo'; }
007 return 'ok';

Der aktuelle Link zum Fragebogen:
https://www.soscisurvey.de/PDG3/?q=Start

Was müssen wir an der frame Verwendung ändern?
by SoSci Survey (327k points)
Eine Variable $IV04_01 gibt es nicht, ich denke, Sie meinen value('IV04_01'), denn Sie interessieren sich ja für eine Variable im Datensatz, nicht im PHP-Code, vgl. https://www.soscisurvey.de/help/doku.php/de:create:variables
by s057462 (330 points)
Ah, ja, stimmt, jetzt funktioniert es!!
mit:
option('nextbutton', false);
if(value('IV04_01' == 2){
    goToPage('GB'); }
else{ goToPage('Demo'); }

Vielen Dank!
by s057462 (330 points)
Hallo noch mal,
wir dachten ja, dass das jetzt funktioniert, die webcam Abfrage und dann die webcam weiterlaufen zu lassen, aber wir haben doch wieder zwei Probleme:
1) eine Fehlermeldung auf der Seite mit der Webcam-Aktivierung:
ReferenceError: surveyFrame is not defined
webcam_frame.html:8:21<anonymous> https://www.soscisurvey.de/PDG3/webcam_frame.html:8

und 2) die webcam wird nach positiver Abfrage angeschaltet aber schaltet sich nach einigen Sekunden auf der gleichen Seite wieder aus.

Haben Sie evtl. für diese beiden Probleme noch mal Hinweise?
Vielen Dank!
by SoSci Survey (327k points)
> ReferenceError: surveyFrame is not defined

Fangen wir einmal damit an... Was sagt denn die Fehlerkonsole, wenn Sie direkt unter die Definition der Variable das console.log() schreiben?

var surveyFrame = window.parent.getElementById("survey");
console.log(surveyFrame)

Und vor allem: Kommt der Fehler dann über oder unter dieser Information? Die Variable muss ja erst definiert werden, bevor man sie verwenden kann.
by s057462 (330 points)
Das ist das Output, wenn wir die Zeile hinzufügen:

Als Fehlermeldungen bekommen wir:
[Log] <frame src="https://www.soscisurvey.de/PDG3/" name="survey" id="survey"> (webcam_prompt.html, line 12)

[Error] The top-level frame has prevented a document with a different security origin from calling getUserMedia.
    permission_prompt (webcam_prompt.html:19)
    Global Code (webcam_prompt.html:35)
[Error] Unhandled Promise Rejection: TypeError: null is not an object (evaluating 'input.value = 2')
    (anonymous function) (webcam_prompt.html:29)
    promiseReactionJob
[Log] <frame src="https://www.soscisurvey.de/PDG3/" name="survey" id="survey"> (webcam_prompt.html, line 12)

[Error] The top-level frame has prevented a document with a different security origin from calling getUserMedia.
    permission_prompt (webcam_prompt.html:19)
    Global Code (webcam_prompt.html:35)
by SoSci Survey (327k points)
> The top-level frame has prevented a document with a different security origin from calling getUserMedia.

Hier hat offenbar die Sicherheitsbeschränkung des Browsers zugeschlagen. Allerdings irritiert mich das "a different security origin", denn alle Ressourcen werden von www.soscisurvey.de geladen, oder?

Sie können im Frameset einmal den allow-Parameter ausprobieren: https://bugs.webkit.org/show_bug.cgi?id=182638#c8

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

...