
Recherche avancée
Autres articles (97)
-
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
-
Ecrire une actualité
21 juin 2013, parPrésentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
Vous pouvez personnaliser le formulaire de création d’une actualité.
Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...) -
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir
Sur d’autres sites (5585)
-
Ffmpeg RTSP stream with size=N/A bitrate=N/A [closed]
6 octobre 2024, par ComycosWhen I try to stream a video it seems to work but bitrate and size are N/A
frame= 277 fps= 26 q=-1.0 size=N/A time=00:00:11.07 bitrate=N/A speed=1.05x


I run the following command to stream a video to a RTSP server :

ffmpeg -re -stream_loop -1 -i idurre-2024-09-17-12h33m19s.mp4 -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/test


The output ffmpeg is like this :


ffmpeg version 7.1 Copyright (c) 2000-2024 the FFmpeg developers
 built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)
 configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/7.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
 libavutil 59. 39.100 / 59. 39.100
 libavcodec 61. 19.100 / 61. 19.100
 libavformat 61. 7.100 / 61. 7.100
 libavdevice 61. 3.100 / 61. 3.100
 libavfilter 10. 4.100 / 10. 4.100
 libswscale 8. 3.100 / 8. 3.100
 libswresample 5. 3.100 / 5. 3.100
 libpostproc 58. 3.100 / 58. 3.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x127704880] st: 0 edit list: 1 Missing key frame while searching for timestamp: 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x127704880] st: 0 edit list 1 Cannot find an index entry before timestamp: 0.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'idurre-2024-09-17-12h33m19s.mp4':
 Metadata:
 major_brand : isom
 minor_version : 0
 compatible_brands: mp41avc1
 creation_time : 2024-09-17T10:34:16.000000Z
 encoder : vlc 3.0.21 stream output
 encoder-eng : vlc 3.0.21 stream output
 Duration: 00:00:55.68, start: 0.000000, bitrate: 16205 kb/s
 Stream #0:0[0x1](eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709, progressive), 1920x1080, 16203 kb/s, 25 fps, 25 tbr, 1000k tbn (default)
 Metadata:
 creation_time : 2024-09-17T10:34:16.000000Z
 handler_name : VideoHandler
 vendor_id : [0][0][0][0]
Stream mapping:
 Stream #0:0 -> #0:0 (copy)
Output #0, rtsp, to 'rtsp://localhost:8554/test':
 Metadata:
 major_brand : isom
 minor_version : 0
 compatible_brands: mp41avc1
 encoder : Lavf61.7.100
 Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709, progressive), 1920x1080, q=2-31, 16203 kb/s, 25 fps, 25 tbr, 90k tbn (default)
 Metadata:
 creation_time : 2024-09-17T10:34:16.000000Z
 handler_name : VideoHandler
 vendor_id : [0][0][0][0]
Press [q] to stop, [?] for help
frame= 516 fps= 26 q=-1.0 size=N/A time=00:00:20.63 bitrate=N/A speed=1.03x 

[q] command received. Exiting.

[out#0/rtsp @ 0x6000008e0240] video:40672KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame= 528 fps= 26 q=-1.0 Lsize=N/A time=00:00:21.11 bitrate=N/A speed=1.02x 



The server I'm streaming to is a MediaMTX which is supposed to receive the stream. It seems to be connected as it logs it :


mediamtx-rtsp | 2024/10/06 10:35:13 INF MediaMTX v1.9.0
mediamtx-rtsp | 2024/10/06 10:35:13 INF configuration loaded from /mediamtx.yml
mediamtx-rtsp | 2024/10/06 10:35:13 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
mediamtx-rtsp | 2024/10/06 10:35:13 INF [SRT] listener opened on :8890 (UDP)
mediamtx-rtsp | 2024/10/06 10:35:16 INF [RTSP] [conn 192.168.65.1:17069] opened
mediamtx-rtsp | 2024/10/06 10:35:16 INF [RTSP] [session b3bb2623] created by 192.168.65.1:17069
mediamtx-rtsp | 2024/10/06 10:35:16 INF [RTSP] [session b3bb2623] is publishing to path 'test', 1 track (H264)



But when I try to read it with ffplay nothing is showing...


-
FFMPEG - copy the SPECIFED tracks only, ignore all others
10 janvier 2024, par GDPI have some very strange MP4 files that we get regularly for processing created by Wowza. Neither FFMPEG or MEDIAINFO can detect that there are subtitles soft-coded in them, but they ARE there, I can extract them with ccextractor, and when they're played, the captions appear later in the video where the actually start in the timeline.


I've tried every variation of copying with/without re-encoding, but all the answers show how to "omit" the subtitles with -sn such as these :


ffmpeg -i 3078.mp4 -c copy -sn 3078_sn.mp4
 ffmpeg -i 3078.mp4 -c:v libx264 -c:a ac3 -map 0:v:0 -map 0:a:1 3078_sn.mp4
 ffmpeg -i 3078.mp4 -map 0:v:0 -map 0:a:0 -map -0:s -map -0:d -c copy 3078_sn2.mp4 -y



FFprobe :


ffprobe 3078.mp4 -hide_banner
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001ef2bcd9e00] multiple fourcc not supported
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '3078.mp4':
 Metadata:
 major_brand : f4v
 minor_version : 0
 compatible_brands: isommp42m4v
 creation_time : 2024-01-09T19:59:28.000000Z
 Duration: 02:17:18.47, start: 0.000000, bitrate: 2165 kb/s
 Stream #0:0[0x1](eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 1902 kb/s, 29.96 fps, 29.97 tbr, 90k tbn (default)
 Metadata:
 creation_time : 2024-01-09T19:59:28.000000Z
 handler_name : WowzaStreamingEngine
 vendor_id : [0][0][0][0]
 encoder : WowzaStreamingEngine
 Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 257 kb/s (default)
 Metadata:
 creation_time : 2024-01-09T19:59:28.000000Z
 handler_name : WowzaStreamingEngine
 vendor_id : [0][0][0][0]
 Stream #0:2[0x3](eng): Data: none (amf0 / 0x30666D61), 1 kb/s (default)
 Metadata:
 creation_time : 2024-01-09T19:59:28.000000Z
 handler_name : WowzaStreamingEngine
Unsupported codec with id 0 for input stream 2



The problem seems to be that FFMPEG isn't detecting they're there, and so copies them anyways. My assumption is that they're not stored in the header of the MP4 properly (or however that's done), so get because they're later detect, but weren't omitted when it checked the header (pure guesswork on that).


So, is there a way to copy ONLY the video, regardless of whatEVER tracks may or not be in the file, then do the same for audio, and then merge the two single-track files ?


-
Why does my ffmpeg audio sound slower and deeper - sample rate mismatch
4 septembre 2020, par yogesh zinzuok so this is a discord bot to record voice chat
https://hatebin.com/hgjlazacri
Now the bot works perfectly fine but the issue is that the audio sounds a bit deeper and slower than normal.. Why does it happen ? how can I make the audio sound 1:1..




const Discord = require('discord.js');
const client = new Discord.Client();
const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
const fs = require('fs-extra')
const mergeStream = require('merge-stream');
const config = require('./config.json');
const { getAudioDurationInSeconds } = require('get-audio-duration');
const cp = require('child_process');
const path1 = require('path');
const Enmap = require('enmap');
const UserRecords = require("./models/userrecords.js")
const ServerRecords = require("./models/serverrecords.js")
let prefix = `$`
class Readable extends require('stream').Readable { _read() {} }
let recording = false;
let currently_recording = {};
let mp3Paths = [];
const silence_buffer = new Uint8Array(3840);
const express = require('express')
const app = express()
const port = 3000
const publicIP = require('public-ip')
const { program } = require('commander');
const { path } = require('@ffmpeg-installer/ffmpeg');
const version = '0.0.1'
program.version(version);
let debug = false
let runProd = false
let fqdn = "";
const mongoose = require("mongoose");
const MongoClient = require('mongodb').MongoClient;
mongoose.connect('SECRRET',{
 useNewUrlParser: true
}, function(err){
 if(err){
 console.log(err);
 }else{
 console.log("Database connection initiated");
 }
});
require("dotenv").config()
function bufferToStream(buffer) {
 let stream = new Readable();
 stream.push(buffer);
 return stream;
}





client.commands = new Enmap();

client.on('ready', async () => {
 console.log(`Logged in as ${client.user.tag}`);

 let host = "localhost"

 

 let ip = await publicIP.v4();

 let protocol = "http";
 if (!runProd) {
 host = "localhost"
 } else {
 host = `35.226.244.186`;
 }
 fqdn = `${protocol}://${host}:${port}`
 app.listen(port, `0.0.0.0`, () => {
 console.log(`Listening on port ${port} for ${host} at fqdn ${fqdn}`)
 })
});
let randomArr = []
let finalArrWithIds = []
let variable = 0
client.on('message', async message => {
 console.log(`fuck`);
 if(message.content === `$record`){
 mp3Paths = []
 finalArrWithIds = []
 let membersToScrape = Array.from(message.member.voice.channel.members.values());
 membersToScrape.forEach((member) => {
 if(member.id === `749250882830598235`) {
 console.log(`botid`);
 }
 else {
 finalArrWithIds.push(member.id)
 }
 
 })
 const randomNumber = Math.floor(Math.random() * 100)
 randomArr = []
 randomArr.push(randomNumber)
 }
 
 
 const generateSilentData = async (silentStream, memberID) => {
 console.log(`recordingnow`)
 while(recording) {
 if (!currently_recording[memberID]) {
 silentStream.push(silence_buffer);
 }
 await new Promise(r => setTimeout(r, 20));
 }
 return "done";
 }
 console.log(generateSilentData, `status`)
 function generateOutputFile(channelID, memberID) {
 const dir = `./recordings/${channelID}/${memberID}`;
 fs.ensureDirSync(dir);
 const fileName = `${dir}/${randomArr[0]}.aac`;
 console.log(`${fileName} ---------------------------`);
 return fs.createWriteStream(fileName);
 }
 
 if (!fs.existsSync("public")) {
 fs.mkdirSync("public");
 }
 app.use("/public", express.static("./public"));
 if (!message.guild) return;

 if (message.content === config.prefix + config.record_command) {
 if (recording) {
 message.reply("bot is already recording");
 return
 }
 if (message.member.voice.channel) {
 recording = true;
 const connection = await message.member.voice.channel.join();
 const dispatcher = connection.play('./audio.mp3');

 connection.on('speaking', (user, speaking) => {
 if (speaking.has('SPEAKING')) {
 currently_recording[user.id] = true;
 } else {
 currently_recording[user.id] = false;
 }
 })


 let members = Array.from(message.member.voice.channel.members.values());
 members.forEach((member) => {

 if (member.id != client.user.id) {
 let memberStream = connection.receiver.createStream(member, {mode : 'pcm', end : 'manual'})

 let outputFile = generateOutputFile(message.member.voice.channel.id, member.id);
 console.log(outputFile, `outputfile here`);
 mp3Paths.push(outputFile.path);
 

 silence_stream = bufferToStream(new Uint8Array(0));
 generateSilentData(silence_stream, member.id).then(data => console.log(data));
 let combinedStream = mergeStream(silence_stream, memberStream);

 ffmpeg(combinedStream)
 .inputFormat('s32le')
 .audioFrequency(44100)
 .audioChannels(2)
 .on('error', (error) => {console.log(error)})
 .audioCodec('aac')
 .format('adts') 
 .pipe(outputFile)
 
 }
 })
 } else {
 message.reply('You need to join a voice channel first!');
 }
 }

 if (message.content === config.prefix + config.stop_command) {

 let date = new Date();
 let dd = String(date.getDate()).padStart(2, '0');
 let mm = String(date.getMonth() + 1).padStart(2, '0'); 
 let yyyy = date.getFullYear();
 date = mm + '/' + dd + '/' + yyyy;





 let currentVoiceChannel = message.member.voice.channel;
 if (currentVoiceChannel) {
 recording = false;
 await currentVoiceChannel.leave();

 let mergedOutputFolder = './recordings/' + message.member.voice.channel.id + `/${randomArr[0]}/`;
 fs.ensureDirSync(mergedOutputFolder);
 let file_name = `${randomArr[0]}` + '.aac';
 let mergedOutputFile = mergedOutputFolder + file_name;
 
 
 let download_path = message.member.voice.channel.id + `/${randomArr[0]}/` + file_name;

 let mixedOutput = new ffmpeg();
 console.log(mp3Paths, `mp3pathshere`);
 mp3Paths.forEach((mp3Path) => {
 mixedOutput.addInput(mp3Path);
 
 })
 console.log(mp3Paths);
 //mixedOutput.complexFilter('amix=inputs=2:duration=longest');
 mixedOutput.complexFilter('amix=inputs=' + mp3Paths.length + ':duration=longest');
 
 let processEmbed = new Discord.MessageEmbed().setTitle(`Audio Processing.`)
 processEmbed.addField(`Audio processing starting now..`, `Processing Audio`)
 processEmbed.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/748610998985818202/speaker.png`)
 processEmbed.setColor(` #00FFFF`)
 const processEmbedMsg = await message.channel.send(processEmbed)
 async function saveMp3(mixedData, outputMixed) {
 console.log(`${mixedData} MIXED `)
 
 
 
 return new Promise((resolve, reject) => {
 mixedData.on('error', reject).on('progress',
 async (progress) => {
 
 let processEmbedEdit = new Discord.MessageEmbed().setTitle(`Audio Processing.`)
 processEmbedEdit.addField(`Processing: ${progress.targetSize} KB converted`, `Processing Audio`)
 processEmbedEdit.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/748610998985818202/speaker.png`)
 processEmbedEdit.setColor(` #00FFFF`)
 processEmbedMsg.edit(processEmbedEdit)
 console.log('Processing: ' + progress.targetSize + ' KB converted');
 }).on('end', () => {
 console.log('Processing finished !');
 resolve()
 }).saveToFile(outputMixed);
 console.log(`${outputMixed} IT IS HERE`);
 })
 }
 // mixedOutput.saveToFile(mergedOutputFile);
 await saveMp3(mixedOutput, mergedOutputFile);
 console.log(`${mixedOutput} IN HEREEEEEEE`);
 // We saved the recording, now copy the recording
 if (!fs.existsSync(`./public`)) {
 fs.mkdirSync(`./public`);
 }
 let sourceFile = `${__dirname}/recordings/${download_path}`
 console.log(`DOWNLOAD PATH HERE ${download_path}`)
 const guildName = message.guild.id;
 const serveExist = `/public/${guildName}`
 if (!fs.existsSync(`.${serveExist}`)) {
 fs.mkdirSync(`.${serveExist}`)
 }
 let destionationFile = `${__dirname}${serveExist}/${file_name}`

 let errorThrown = false
 try {
 fs.copySync(sourceFile, destionationFile);
 } catch (err) {
 errorThrown = true
 await message.channel.send(`Error: ${err.message}`)
 }
 const usersWithTag = finalArrWithIds.map(user => `\n <@${user}>`);
 let timeSpent = await getAudioDurationInSeconds(`public/${guildName}/${file_name}`)
 let timesSpentRound = Math.floor(timeSpent)
 let finalTimeSpent = timesSpentRound / 60
 let finalTimeForReal = Math.floor(finalTimeSpent)
 if(!errorThrown){
 //--------------------- server recording save START
 class GeneralRecords {
 constructor(generalLink, date, voice, time) {
 this.generalLink = generalLink;
 this.date = date;
 this.note = `no note`;
 this.voice = voice;
 this.time = time
 }
 }
 let newGeneralRecordClassObject = new GeneralRecords(`${fqdn}/public/${guildName}/${file_name}`, date, usersWithTag, finalTimeForReal)
 let checkingServerRecord = await ServerRecords.exists({userid: `server`})
 if(checkingServerRecord === true){
 existingServerRecord = await ServerRecords.findOne({userid: `server`})
 existingServerRecord.content.push(newGeneralRecordClassObject)
 await existingServerRecord.save()
 }
 if(checkingServerRecord === false){
 let serverRecord = new ServerRecords()
 serverRecord.userid = `server`
 serverRecord.content.push(newGeneralRecordClassObject)
 await serverRecord.save()
 }
 //--------------------- server recording save STOP
 }
 
 //--------------------- personal recording section START
 for( member of finalArrWithIds) {

 let personal_download_path = message.member.voice.channel.id + `/${member}/` + file_name;
 let sourceFilePersonal = `${__dirname}/recordings/${personal_download_path}`
 let destionationFilePersonal = `${__dirname}${serveExist}/${member}/${file_name}`
 await fs.copySync(sourceFilePersonal, destionationFilePersonal);
 const user = client.users.cache.get(member);
 console.log(user, `user here`);
 try {
 ffmpeg.setFfmpegPath(ffmpegInstaller.path);
 
 ffmpeg(`public/${guildName}/${member}/${file_name}`)
 .audioFilters('silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-90dB')
 .output(`public/${guildName}/${member}/personal-${file_name}`)
 .on(`end`, function () {
 console.log(`DONE`);
 })
 .on(`error`, function (error) {
 console.log(`An error occured` + error.message)
 })
 .run();
 
 }
 catch (error) {
 console.log(error)
 }
 

 // ----------------- SAVING PERSONAL RECORDING TO DATABASE START
 class PersonalRecords {
 constructor(generalLink, personalLink, date, time) {
 this.generalLink = generalLink;
 this.personalLink = personalLink;
 this.date = date;
 this.note = `no note`;
 this.time = time;
 }
 }
 let timeSpentPersonal = await getAudioDurationInSeconds(`public/${guildName}/${file_name}`)
 let timesSpentRoundPersonal = Math.floor(timeSpentPersonal)
 let finalTimeSpentPersonal = timesSpentRoundPersonal / 60
 let finalTimeForRealPersonal = Math.floor(finalTimeSpentPersonal)
 let newPersonalRecordClassObject = new PersonalRecords(`${fqdn}/public/${guildName}/${file_name}`, `${fqdn}/public/${guildName}/${member}/personal-${file_name}`, date, finalTimeForRealPersonal)

 let checkingUserRecord = await UserRecords.exists({userid: member})
 if(checkingUserRecord === true){
 existingUserRecord = await UserRecords.findOne({userid: member})
 existingUserRecord.content.push(newPersonalRecordClassObject)
 await existingUserRecord.save()
 }
 if(checkingUserRecord === false){
 let newRecord = new UserRecords()
 newRecord.userid = member
 newRecord.content.push(newPersonalRecordClassObject)
 await newRecord.save()
 }


 
 // ----------------- SAVING PERSONAL RECORDING TO DATABASE END
 

 const endPersonalEmbed = new Discord.MessageEmbed().setTitle(`Your performance was amazing ! Review it here :D`)
 endPersonalEmbed.setColor('#9400D3')
 endPersonalEmbed.setThumbnail(`https://media.discordapp.net/attachments/730811581046325348/745381641324724294/vinyl.png`)
 endPersonalEmbed.addField(`1