Recherche avancée

Médias (91)

Autres articles (56)

  • Mise à jour de la version 0.1 vers 0.2

    24 juin 2013, par

    Explications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
    Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...)

  • MediaSPIP v0.2

    21 juin 2013, par

    MediaSPIP 0.2 est la première version de MediaSPIP stable.
    Sa date de sortie officielle est le 21 juin 2013 et est annoncée ici.
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Comme pour la version précédente, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

  • MediaSPIP version 0.1 Beta

    16 avril 2011, par

    MediaSPIP 0.1 beta est la première version de MediaSPIP décrétée comme "utilisable".
    Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
    Pour avoir une installation fonctionnelle, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
    Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...)

Sur d’autres sites (7732)

  • stream_encoder.c : Fix compiler warning

    13 décembre 2015, par Erik de Castro Lopo
    stream_encoder.c : Fix compiler warning
    

    Remove incorrect assignment to `encoder->protected_->state`.

    • [DH] src/libFLAC/stream_encoder.c
  • How to fix here "EPIPE" in Node js Socket.io

    23 avril, par Mehdi008

    Receiving this error :

    


    Error: write EPIPE
        at afterWriteDispatched (node:internal/stream_base_commons:161:15)
        at writeGeneric (node:internal/stream_base_commons:152:3)
        at Socket._writeGeneric (node:net:958:11)
        at Socket._write (node:net:970:8)
        at doWrite (node:internal/streams/writable:598:12)
        at clearBuffer (node:internal/streams/writable:783:7)
        at onwrite (node:internal/streams/writable:653:7)
        at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:107:10)
    Emitted 'error' event on Socket instance at:
        at emitErrorNT (node:internal/streams/destroy:169:8)
        at emitErrorCloseNT (node:internal/streams/destroy:128:3)
        at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
      errno: -4047,
      code: 'EPIPE',
      syscall: 'write'
    }


    


    // for this code: const { spawn } = require("child_process");

module.exports = (socket, pool) => {
    
    let stream_req_token = "";
    let rtmps_array = [];

    socket.on("stream_request_token",async(token)=>{

        const stream_reqs = await pool`SELECT * FROM stream_request WHERE token=${token}`;


        if(stream_reqs.length === 0){
            
            socket.emit("token_validation_response",false);
            return;
        }

        const stream_req = stream_reqs[0];

        if(!stream_req.is_valid){

            socket.emit("token_validation_response",false);
            return;
        }

        socket.emit("token_validation_response",true);

        stream_req_token = token;


    })

    socket.on("rtmps_array",async(array)=>{

        try{

            const rtmps = JSON.parse(array);

        const streams_requests = await pool`SELECT id FROM stream_request WHERE token=${stream_req_token}`;
        const stream_req_id = streams_requests[0].id;

        rtmps_array = rtmps;

        rtmps.map(async(rtmp)=>{

            await pool`INSERT INTO stream (platform,url,url_key,stream_request_id) 
            VALUES(${rtmp.platform},${rtmp.url},${rtmp.key},${stream_req_id})`;
        })

        socket.emit("rtmps_array_response",true);

        } catch(err){

            console.log(err);
            socket.emit("rtmps_array_response",false);

        }


    })

    //Start Streaming
    let ffmpegProcess = null;
    let isStreaming = false; // Flag to track streaming state

  socket.on("stream", (chunk) => {
    if (!ffmpegProcess) {
        console.log('Initializing FFmpeg process...');

        // Spawn FFmpeg process
        const resolution = "1280x720"; // Change to "1920x1080" for 1080p

        const ffmpegArgs = [
            "-i", "pipe:0", // Input from stdin
            "-c:v", "libx264", // Video codec
            "-preset", "veryfast", // Low latency encoding
            "-b:v", "4500k", // Target average bitrate (4.5 Mbps)
            "-minrate", "2500k", // Minimum bitrate
            "-maxrate", "6000k", // Maximum bitrate
            "-bufsize", "16000k", // Buffer size (twice the max bitrate)
            "-r", "30", // **FORCE 30 FPS**
            "-g", "60", // Keyframe interval (every 2 seconds)
            "-tune", "zerolatency", // Low latency tuning
            "-sc_threshold", "0", // Constant bitrate enforcement
            "-flags", "+global_header",
          
            // **Resolution Fix**
            "-s", resolution, // **Set resolution to 720p or 1080p**
            "-aspect", "16:9", // **Maintain aspect ratio**
            
            // **Frame Rate Fix**
            "-vsync", "cfr", // **Forces Constant Frame Rate (CFR)**
            "-fps_mode", "cfr", // **Prevents FFmpeg from auto-adjusting FPS**
            
            // Audio settings
            "-c:a", "aac",
            "-b:a", "128k", // Audio bitrate
            "-ar", "44100", // Audio sample rate
            "-ac", "2", // Stereo audio
          
            "-f", "flv" // Output format
          ];
      
          // Map the streams to multiple RTMP destinations
          rtmps_array.forEach((rtmp) => {
            ffmpegArgs.push("-map", "0:v:0", "-map", "0:a:0", "-f", "flv", `${rtmp.url}/${rtmp.key}`);
          });
      
          // Spawn FFmpeg process
          ffmpegProcess = spawn("ffmpeg", ffmpegArgs);

        ffmpegProcess.stderr.on('data', (data) => {
            console.log(`FFmpeg STDERR: ${data}`);
    });

        ffmpegProcess.on('close', (code) => {
            console.log(`FFmpeg process closed with code ${code}`);
            ffmpegProcess = null; // Reset process
            isStreaming = false; // Reset streaming state
        });

        ffmpegProcess.on('error', (err) => {
            console.error(`FFmpeg process error: ${err.message}`);
            ffmpegProcess = null; // Reset process
            isStreaming = false; // Reset streaming state
        });

        console.log('FFmpeg process started.');
        isStreaming = true; // Set streaming state to true
    }

    // Write chunk to FFmpeg process
    if (isStreaming && ffmpegProcess && ffmpegProcess.stdin && !ffmpegProcess.stdin.destroyed) {
        try {
            ffmpegProcess.stdin.write(chunk); // Write chunk to stdin
            console.log('Chunk written to FFmpeg.');
        } catch (err) {
            console.error('Error writing chunk to FFmpeg stdin:', err.message);
        }
    } else {
        console.error('FFmpeg process or stdin is not ready.');
    }
});

socket.on("stop-stream", async() => {
    console.log('Stream Stopped.');

    if(stream_req_token.length !== 0){

        await pool`UPDATE stream_request 
               SET is_valid=false
               WHERE token=${stream_req_token}`

        await pool`DELETE FROM current_streams WHERE id=${stream_req_token}`;       
    }

    if (ffmpegProcess) {
        isStreaming = false; // Set streaming state to false

        try {
            // Check if stdin is open before closing
            if (ffmpegProcess.stdin) {
                ffmpegProcess.stdin.end(); // End stdin safely
            }

            // Wait for FFmpeg to close before setting to null
            ffmpegProcess.on("close", () => {
                console.log("FFmpeg process closed.");
                ffmpegProcess = null;
            });

            // Kill FFmpeg process
            ffmpegProcess.kill("SIGTERM"); // Use SIGTERM for graceful exit

        } catch (err) {
            console.error("Error while stopping FFmpeg:", err.message);
        }
    } else {
        console.log("No active FFmpeg process.");
    }
});


socket.on('error', (err) => {
  console.error('Socket error:', err);
});

socket.on("disconnect", async() => {
    console.log('Client Disconnected.');

    if(stream_req_token.length !== 0){

        await pool`UPDATE stream_request 
               SET is_valid=false
               WHERE token=${stream_req_token}`;

        await pool`DELETE FROM current_streams WHERE id=${stream_req_token}`;       

    }
    
    if (ffmpegProcess) {
        isStreaming = false; // Set streaming state to false

        try {
            // Check if stdin is open before closing
            if (ffmpegProcess.stdin) {
                ffmpegProcess.stdin.end(); // End stdin safely
            }

            // Wait for FFmpeg to close before setting to null
            ffmpegProcess.on("close", () => {
                console.log("FFmpeg process closed.");
                ffmpegProcess = null;
            });

            // Kill FFmpeg process
            ffmpegProcess.kill("SIGTERM"); // Use SIGTERM for graceful exit


        } catch (err) {
            console.error("Error while stopping FFmpeg:", err.message);
        }
    } else {
        console.log("No active FFmpeg process.");
    }
});

};


    


    


  • Gstreamer convert and display video v4l2 - tee problems in rust

    27 mars 2023, par d3im

    I have USB grabber v4l2 source and I want to tee stream to autovideosink and x264enc to file (now as fake black hole)

    


    When I disable one or another branch it works but together Pipeline goes :

    


    Pipeline state changed from Null to Ready
Pipeline state changed from Ready to Paused


    


    and stays there never switches to Playing

    


    gst-launch-1.0 with similar functionality works well.

    


        gst::Element::link_many(&[&pw_video, &v_caps, &vid_queuey, &vid_tee]).unwrap();
    gst::Element::link_many(&[&vid_queue1, &autovideoconvert, &vid_queuex, &autovideosink]).unwrap();
    gst::Element::link_many(&[&vid_queue2, &autovideoconvert_x264, &vid_queue3, &x264, &vid_queue4, &fake]).unwrap();

    let tee_display_pad = vid_tee.request_pad_simple("src_10").unwrap();
    let vid_queue1_pad = vid_queue1.static_pad("sink").unwrap();

    tee_display_pad.link(&vid_queue1_pad).unwrap();

    let tee_convert_pad = vid_tee.request_pad_simple("src_20").unwrap();
    let vid_queue2_pad = vid_queue2.static_pad("sink").unwrap();

    tee_convert_pad.link(&vid_queue2_pad).unwrap();


    


    How can I use tee in rust properly to have playable pipeline with two branches ?

    


    Update : I read some posts about increasing queue size, so I tried for this and then all queues :

    


        let vid_queue1 = gst::ElementFactory::make("queue")
        .name("queue1")
        .property("max-size-buffers", 5000 as u32)
        .property("max-size-bytes", 1048576000 as u32)
        .property("max-size-time", 60000000000 as u64)
        .build()
        .expect("queue1");


    


    but it didn't help so I tried set zero latency :

    


        let x264 = gst::ElementFactory::make("x264enc")
        .name("x264")
        .property_from_str("speed-preset", "ultrafast")
        .property_from_str("pass", "qual")
        .property_from_str("tune", "zerolatency")
        .property("quantizer", 0 as u32)
        .property("threads", 8 as u32)
        .build()
        .expect("!x264");


    


    and it works now. But comparable gst-launch-1.0 settings didn't had such option - only queues sizes increased.

    


    Is there any other option than setting zerolatency ?