
Recherche avancée
Médias (1)
-
Rennes Emotion Map 2010-11
19 octobre 2011, par
Mis à jour : Juillet 2013
Langue : français
Type : Texte
Autres articles (46)
-
Les autorisations surchargées par les plugins
27 avril 2010, parMediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs -
Les tâches Cron régulières de la ferme
1er décembre 2010, parLa gestion de la ferme passe par l’exécution à intervalle régulier de plusieurs tâches répétitives dites Cron.
Le super Cron (gestion_mutu_super_cron)
Cette tâche, planifiée chaque minute, a pour simple effet d’appeler le Cron de l’ensemble des instances de la mutualisation régulièrement. Couplée avec un Cron système sur le site central de la mutualisation, cela permet de simplement générer des visites régulières sur les différents sites et éviter que les tâches des sites peu visités soient trop (...) -
Other interesting software
13 avril 2011, parWe don’t claim to be the only ones doing what we do ... and especially not to assert claims to be the best either ... What we do, we just try to do it well and getting better ...
The following list represents softwares that tend to be more or less as MediaSPIP or that MediaSPIP tries more or less to do the same, whatever ...
We don’t know them, we didn’t try them, but you can take a peek.
Videopress
Website : http://videopress.com/
License : GNU/GPL v2
Source code : (...)
Sur d’autres sites (8946)
-
stream_encoder.c : Fix compiler warning
13 décembre 2015, par Erik de Castro Lopo -
How to fix here "EPIPE" in Node js Socket.io
23 avril, par Mehdi008Receiving 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 d3imI 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 ?