0

I'm trying to learn how tu use firebase and its storage option for web apps. So I'm using an older webpage I did to record the save locally a video from webcam. I'm trying to modify it to send the video to the storage instead of downloading it.
Here is the code :
main.html :

<html lang="fr">
    <head>
        <meta charset="utf-8"/>
        <title>Test storage</title>
        <!-- JS -->
            <!-- API -->
            <script src="./javascript/firebase_using.js" type="module"></script>
            <!-- Personal scripts -->
            <script src="./javascript/webcam.js"></script>

        <!-- CSS -->
        <link rel="stylesheet" href="./css/collect.css">
    </head>
    <body>
        <main>
            <div class="content">
                <div class="part user_feedback">
                    <video id="camera" class="camera" src="" width="172" height="172" autoplay></video>
                    <div class="buttons_containors">
                        <button class="button" onclick="startRecording()">Start</button>
                        <button class="button" onclick="stopRecording()">Stop</button>
                    </div>
                </div>

                <div class="part instructions">
                    <video id="demonstration" class="demonstration" src="./ressources page/demo.mp4" width="172" height="172" autoplay loop></video>
                </div>
            </div>
        </main>
    </body>
</html>

classes are used only for css selection, but it's useless to share it here I guess ?

webcam.js :

var recorder = null;
var stream;
var liveStream; 
var blobVideoCouleur;
var URLvideoCouleur;
var FPS = 5;

const contraintes = {
    video: { width: 172, height: 172, frameRate : FPS}
};

window.addEventListener('DOMContentLoaded', demarrerApp); // Waiting for all elements to be loaded

/* FUNCTIONS */

function demarrerApp(){
    initialiseVariables(); // initialising global var
    cameraShow(); // launching camera
}

function initialiseVariables(){
    liveStream = document.getElementById("camera");
}

function cameraShow()
{
    if('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {        
        navigator.mediaDevices.getUserMedia(contraintes) 
        .then(function(mediaStream){
            stream = mediaStream;
            liveStream.srcObject = stream;
        })
        .catch (function(error) {
        console.error("CameraShow : Impossible d'accéder à la caméra : %o", error);
        return;
        })
    }else(console.error("CameraShow : getUserMedia indisponible - Mettez le navigateur à jour"))
}

function startRecording()
{
    recorder = new MediaRecorder(stream);
    let chunks = [];

    recorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
            chunks.push(event.data)
        }
    }

    recorder.onstop = () => { 
        const blob = new Blob(chunks, { 
            type: 'video/webm'
        })
        chunks = [];
        URLvideoCouleur = URL.createObjectURL(blob);
        blobVideoCouleur = blob; 
    }
    
    recorder.start(200);
}

async function stopRecording() {

    for (let track of stream.getTracks()) {
        track.stop();
    }
    // sauvegarder("video_de_test.webm", blobVideoCouleur);
}

firebase_using.js :

import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-analytics.js";
import { getStorage, ref, uploadBytes} from "https://www.gstatic.com/firebasejs/9.22.0/firebase-storage.js";


// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
    apiKey: "...",
    authDomain: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "...",
    appId: "...",
    measurementId: "..."
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const storage = getStorage(app);

function say_hello(){
    console.log("Ohayo Sekai!");
}

function sauvegarder(nom, fichier){
    const storageRef = ref(storage, nom);
    uploadBytes(storageRef, fichier).then((snapshot) => {
        console.log("vidéo mise sur le drive");
    });
}    

the function say_hello() is so useless, just a test function for calling something without parameters

So, all this code do not generate any errors. main.html and webcam.js have expected behavior when I use my function for local downloading (note here, page is long enough.) BUT ! When I use sauvegarder function (so when I uncoment the line // sauvegarder("video_de_test.webm", blobVideoCouleur); in webcam.js) I've the error : "Uncaught (in promise) ReferenceError: sauvegarder is not defined" that I don't understand, cause if use few console.log("...") in my js files, I see firebase_use.js is rode properly, and before webcam.js so basically, the function should be defined... shouldn't it ? For me it's the common way to use a function defined in another file, i just have to be careful of the order of the js files in my html.

So I naively tried to move the function into webcam.js, but then it's ref function that's not defined. Is everything in this file useless outside ?! :O So let's move all firebase_use.js at the beggining of webcam.js aaand... new error : It seems I can't use import statement outside of a module. So webcam.js is now imported as a module into the html ? But the functions startRecording() and stopRecording() are no longer available for my two buttons. So the issue come from the parameter `type="module" when I load a script into html ? It made all functions like... "private" ? How can I solve this ?

Thanks for help !

5
  • I'm not very familiar with type="module" but maybe you need to export the function. Commented May 23, 2023 at 21:22
  • Adding type="module" to a script tag isolates it from the global namespace. You need to explicitly attach methods to the global scope for them to be accessible outside the module (e.g. window.sauvegarder = sauvegarder at the bottom of your firebase_using.js file). See this thread for more details. Commented May 24, 2023 at 1:54
  • Additionally, make sure that your sauvegarder function correctly returns its promise so that it can be chained to and its errors handled. Commented May 24, 2023 at 1:55
  • Hey @samthecodingman @ Barman ! it works ! excellent ! I'm so happy, it's my first time saving a file out of my computer with a webpage ! Now let's explore all others firebase options !! May i'll check options to send messages and have an awesome "contact" form !!! :D <3 Do one of you two want to use "answer the question" button so i choose your answers as solution ? (to close subject / reputation). How wait ? why a console.log after calling sauvegarder don't work ? is it about this promise return ?? Commented May 24, 2023 at 8:48
  • hoho it seems uploadBytes is asynchronous, so using await statement before (and defining sauvegarder as async of course) solves the issue ! Commented May 24, 2023 at 9:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.