
Recherche avancée
Médias (91)
-
#3 The Safest Place
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#4 Emo Creates
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#2 Typewriter Dance
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#1 The Wires
11 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
ED-ME-5 1-DVD
11 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Audio
-
Revolution of Open-source and film making towards open film making
6 octobre 2011, par
Mis à jour : Juillet 2013
Langue : English
Type : Texte
Autres articles (31)
-
Librairies et binaires spécifiques au traitement vidéo et sonore
31 janvier 2010, parLes logiciels et librairies suivantes sont utilisées par SPIPmotion d’une manière ou d’une autre.
Binaires obligatoires FFMpeg : encodeur principal, permet de transcoder presque tous les types de fichiers vidéo et sonores dans les formats lisibles sur Internet. CF ce tutoriel pour son installation ; Oggz-tools : outils d’inspection de fichiers ogg ; Mediainfo : récupération d’informations depuis la plupart des formats vidéos et sonores ;
Binaires complémentaires et facultatifs flvtool2 : (...) -
Support audio et vidéo HTML5
10 avril 2011MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...) -
De l’upload à la vidéo finale [version standalone]
31 janvier 2010, parLe chemin d’un document audio ou vidéo dans SPIPMotion est divisé en trois étapes distinctes.
Upload et récupération d’informations de la vidéo source
Dans un premier temps, il est nécessaire de créer un article SPIP et de lui joindre le document vidéo "source".
Au moment où ce document est joint à l’article, deux actions supplémentaires au comportement normal sont exécutées : La récupération des informations techniques des flux audio et video du fichier ; La génération d’une vignette : extraction d’une (...)
Sur d’autres sites (5175)
-
Error initializing FFmpegKit : "TypeError : Cannot read property 'getLogLevel' of null" in React Native
9 janvier, par Md Monirozzaman khanI'm developing a React Native application where I need to process videos using the ffmpeg-kit-react-native library. However, I'm encountering an issue during the initialization of FFmpegKitConfig. The error message is :


ERROR Error initializing FFmpegKit: [TypeError: Cannot read property 'getLogLevel' of null]



Here is my App.js code




import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Alert, Dimensions, ScrollView, LayoutAnimation, UIManager, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as FileSystem from 'expo-file-system';
import { Video } from 'expo-av';
import { MaterialIcons } from '@expo/vector-icons';
import { FFmpegKit, FFmpegKitConfig, ReturnCode } from 'ffmpeg-kit-react-native';

const windowWidth = Dimensions.get('window').width;

if (Platform.OS === 'android') {
 UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
}

export default function App() {
 const [videoFiles, setVideoFiles] = useState([]);
 const [isGridView, setIsGridView] = useState(false);
 const [isConverting, setIsConverting] = useState(false);

 useEffect(() => {
 FFmpegKitConfig.init()
 .then(() => {
 console.log('FFmpegKit initialized');
 })
 .catch((error) => {
 console.error('Error initializing FFmpegKit:', error);
 });
 }, []);

 const pickVideo = async () => {
 const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
 if (status !== 'granted') {
 alert('Sorry, we need media library permissions to make this work!');
 return;
 }

 let result = await ImagePicker.launchImageLibraryAsync({
 mediaTypes: ImagePicker.MediaTypeOptions.Videos,
 allowsMultipleSelection: true,
 });

 if (!result.canceled && result.assets.length > 0) {
 const newFiles = result.assets.filter(
 (newFile) => !videoFiles.some((existingFile) => existingFile.uri === newFile.uri)
 );

 if (newFiles.length < result.assets.length) {
 Alert.alert('Duplicate Files', 'Some files were already added.');
 }

 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
 setVideoFiles([...videoFiles, ...newFiles]);
 }
 };

 const convertVideos = async () => {
 setIsConverting(true);
 const outputDir = `${FileSystem.documentDirectory}Output`;

 const dirInfo = await FileSystem.getInfoAsync(outputDir);
 if (!dirInfo.exists) {
 await FileSystem.makeDirectoryAsync(outputDir, { intermediates: true });
 }

 for (const video of videoFiles) {
 const { uri } = video;
 const filename = uri.split('/').pop();
 const outputFilePath = `${outputDir}/${filename.split('.').slice(0, -1).join('.')}_modified.mp4`;

 const ffmpegCommand = `-y -i "${uri}" -af "atempo=1.02, bass=g=4:f=80:w=3, treble=g=4:f=3200:w=3, firequalizer=gain_entry='entry(0,0);entry(62,2);entry(125,1.5);entry(250,1);entry(500,1);entry(1000,1);entry(2000,1.5);entry(4000,2.5);entry(8000,3);entry(16000,4)', compand=attacks=0.05:decays=0.25:points=-80/-80-50/-15-30/-10-10/-2:soft-knee=4:gain=2, deesser, highpass=f=35, lowpass=f=17000, loudnorm=I=-16:LRA=11:TP=-1.5, volume=3.9dB" -c:v copy -c:a aac -b:a 224k -ar 48000 -threads 0 "${outputFilePath}"`;

 try {
 const session = await FFmpegKit.execute(ffmpegCommand);
 const returnCode = await session.getReturnCode();

 if (ReturnCode.isSuccess(returnCode)) {
 console.log(`Video converted: ${outputFilePath}`);
 } else if (ReturnCode.isCancel(returnCode)) {
 console.log('Conversion cancelled');
 } else {
 console.error(`FFmpeg process failed: ${session.getFailStackTrace()}`);
 }
 } catch (error) {
 console.error(`Error converting video: ${error.message}`);
 }
 }

 setIsConverting(false);
 Alert.alert('Conversion Complete', 'All videos have been converted.');
 };

 const deleteVideo = (uri) => {
 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
 setVideoFiles(videoFiles.filter((video) => video.uri !== uri));
 };

 const clearAllVideos = () => {
 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
 setVideoFiles([]);
 };

 const toggleLayout = () => {
 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
 setIsGridView(!isGridView);
 };

 return (
 <view style="{styles.container}">
 <text style="{styles.header}">Video Converter App</text>
 <touchableopacity style="{styles.addButton}">
 <text style="{styles.addButtonText}">Select or Browse Videos</text>
 </touchableopacity>
 <view style="{styles.headerContainer}">
 <text style="{styles.videoCount}">Total Videos: {videoFiles.length}</text>
 {videoFiles.length > 0 && (
 <>
 <touchableopacity style="{styles.clearButtonContainer}">
 <materialicons size="{24}" color="red" style="{styles.clearIcon}"></materialicons>
 <text style="{styles.clearAllText}">Clear All</text>
 </touchableopacity>
 <touchableopacity style="{styles.toggleLayoutButton}">
 <materialicons size="{24}" color="#fff"></materialicons>
 </touchableopacity>
 >
 )}
 </view>
 {isGridView ? (
 <scrollview contentcontainerstyle="{styles.gridContainer}">
 {videoFiles.map((item, index) => (
 <view key="{index}" style="{styles.videoItemGrid}">
 
 <touchableopacity>> deleteVideo(item.uri)} style={styles.deleteButtonGrid}>
 <materialicons size="{24}" color="red"></materialicons>
 </touchableopacity>
 </view>
 ))}
 </scrollview>
 ) : (
 <view style="{styles.list}">
 {videoFiles.map((item, index) => (
 <view key="{index}" style="{styles.videoItem}">
 
 <text style="{styles.fileName}">{decodeURI(item.fileName || item.uri.split('/').pop() || 'Unknown File')}</text>
 <touchableopacity>> deleteVideo(item.uri)} style={styles.deleteButton}>
 <materialicons size="{24}" color="red"></materialicons>
 </touchableopacity>
 </view>
 ))}
 </view>
 )}
 {videoFiles.length > 0 && (
 <touchableopacity style="{styles.convertButton}" disabled="{isConverting}">
 <text style="{styles.convertButtonText}">{isConverting ? 'Converting...' : 'Convert'}</text>
 </touchableopacity>
 )}
 </view>
 );
}

const styles = StyleSheet.create({
 container: {
 flex: 1,
 backgroundColor: '#fff',
 alignItems: 'center',
 padding: 10,
 },
 header: {
 fontSize: 24,
 fontWeight: 'bold',
 marginBottom: 5,
 },
 addButton: {
 backgroundColor: '#007BFF',
 padding: 15,
 borderRadius: 10,
 alignItems: 'center',
 marginBottom: 5,
 width: '100%',
 elevation: 2,
 shadowColor: '#000',
 shadowOffset: { width: 0, height: 5 },
 shadowOpacity: 0.8,
 shadowRadius: 2,
 },
 addButtonText: {
 color: '#fff',
 fontSize: 18,
 fontWeight: 'bold',
 },
 headerContainer: {
 flexDirection: 'row',
 alignItems: 'center',
 justifyContent: 'space-between',
 width: '100%',
 marginBottom: 10,
 },
 videoCount: {
 fontSize: 18,
 },
 clearButtonContainer: {
 flexDirection: 'row',
 alignItems: 'center',
 marginRight: 10,
 },
 clearIcon: {
 marginRight: 5,
 },
 clearAllText: {
 fontSize: 16,
 color: 'red',
 textDecorationLine: 'underline',
 },
 toggleLayoutButton: {
 backgroundColor: '#007BFF',
 padding: 1,
 borderRadius: 8,
 alignItems: 'center',
 justifyContent: 'center',
 },
 list: {
 flex: 1,
 width: '100%',
 },
 videoItem: {
 padding: 5,
 borderBottomColor: '#ccc',
 borderBottomWidth: 0.7,
 flexDirection: 'row',
 alignItems: 'center',
 },
 videoItemGrid: {
 flexDirection: 'column',
 alignItems: 'center',
 margin: 4,
 borderWidth: 1,
 borderColor: '#ccc',
 borderRadius: 8,
 padding: 2,
 position: 'relative',
 },
 thumbnail: {
 width: 70,
 height: 70,
 marginRight: 10,
 },
 thumbnailGrid: {
 width: 80,
 height: 80,
 marginBottom: 0,
 },
 fileName: {
 fontSize: 16,
 marginLeft: 10,
 flex: 1,
 },
 deleteButton: {
 marginLeft: 60,
 width: 20,
 height: 20,
 },
 deleteButtonGrid: {
 position: 'absolute',
 bottom: 5,
 right: 5,
 },
 convertButton: {
 backgroundColor: '#007BFF',
 padding: 15,
 borderRadius: 10,
 alignItems: 'center',
 marginTop: 20,
 width: '100%',
 },
 convertButtonText: {
 color: '#fff',
 fontSize: 18,
 fontWeight: 'bold',
 },
 gridContainer: {
 flexDirection: 'row',
 flexWrap: 'wrap',
 justifyContent: 'flex-start',
 paddingVertical: 5,
 paddingHorizontal: 5,
 width: '100%',
 },
});







App.json




{
 "expo": {
 "name": "VidoeConvert",
 "slug": "VidoeConvert",
 "version": "1.0.0",
 "orientation": "portrait",
 "icon": "./assets/icon.png",
 "userInterfaceStyle": "light",
 "splash": {
 "image": "./assets/splash.png",
 "resizeMode": "contain",
 "backgroundColor": "#ffffff"
 },
 "ios": {
 "supportsTablet": true
 },
 "android": {
 "adaptiveIcon": {
 "foregroundImage": "./assets/adaptive-icon.png",
 "backgroundColor": "#ffffff"
 },
 "package": "com.anonymous.VidoeConvert"
 },
 "web": {
 "favicon": "./assets/favicon.png"
 },
 "plugins": [
 "@config-plugins/ffmpeg-kit-react-native",
 "expo-build-properties"
 ]
 }
}







Package.json




{
 "name": "vidoeconvert",
 "version": "1.0.0",
 "main": "expo/AppEntry.js",
 "scripts": {
 "start": "expo start",
 "android": "expo run:android",
 "ios": "expo run:ios",
 "web": "expo start --web"
 },
 "dependencies": {
 "@config-plugins/ffmpeg-kit-react-native": "^8.0.0",
 "@expo/metro-runtime": "~3.2.1",
 "expo": "~51.0.17",
 "expo-asset": "~10.0.10",
 "expo-av": "^14.0.6",
 "expo-document-picker": "~12.0.2",
 "expo-file-system": "~17.0.1",
 "expo-image-picker": "~15.0.7",
 "expo-media-library": "~16.0.4",
 "expo-status-bar": "~1.12.1",
 "ffmpeg-kit-react-native": "^6.0.2",
 "react": "18.2.0",
 "react-dom": "18.2.0",
 "react-native": "^0.74.3",
 "react-native-document-picker": "^9.3.0",
 "react-native-ffmpeg": "^0.5.2",
 "react-native-vector-icons": "^10.1.0",
 "react-native-web": "~0.19.10",
 "expo-build-properties": "~0.12.3"
 },
 "devDependencies": {
 "@babel/core": "^7.20.0"
 },
 "private": true
}







Has anyone encountered a similar issue or can point me in the right direction to resolve this error ? Any help would be greatly appreciated !


How to remove the error ?


any configruation required for this project ?


-
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.");
 }
});

};





-
What format/protocol does ffmpeg use for "raw" output ?
18 avril 2017, par MSaltersGiven a commandline
ffmpeg -f lavfi -i "sine=frequency=1000:duration=5" -ar 8000 -c:a FOO pipe:1
, ffmpeg might complain it’s "unable to find a suitable output format". For some codecs, ffmpeg has a default container format, e.g.-c:a libmp3lame
will produce MP3’s. For other codecs, you just repeat yourself (sort of) :-c:a pcm_alaw -f alaw
But what if I want to stream the raw codec output, and there’s no matching
-f
? Can I just take-f alaw
and assume that it doesn’t do anything ? (G711 alaw is a simple codec which produces a byte stream, so-f alaw
presumably just copies that byte stream)Obviously the other side of the pipe needs to know how the data stream needs to be interpreted, if there’s no container info. But assume that I already know the other side of the pipe is expecting an audio stream, sampled at 8 kHz, encoded with
-c:a FOO
.