Newest 'ffmpeg' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/ffmpeg

Les articles publiés sur le site

  • FFmpeg Android Errors

    17 février, par axjp

    Ok so im making a kotlin android app and for file conversion from 3gp to wav i added the android ffmpeg library with implementation 'com.arthenica:mobile-ffmpeg-full:4.4' then i added this code to convert the files FFmpeg.execute("-i" + f2 +"/storage/emulated/0/Android/data/com.icompilecodewithnowarnings.ffmpegthing/files/Documents/recording.wav") for further context f2 is /storage/emulated/0/Android/data/com.icompilecodewithnowarnings.ffmpegthing/files/Documents/recording.3gp

    The error log is to large to simply just fit here but heres some of it

    Execution failed for task ':app:checkDebugAarMetadata'.
    > Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
       > Could not find com.github.hiteshsondhi88.libffmpeg:FFmpegAndroid:0.3.2.
         Searched in the following locations:
           - https://dl.google.com/dl/android/maven2/com/github/hiteshsondhi88/libffmpeg/FFmpegAndroid/0.3.2/FFmpegAndroid-0.3.2.pom
           - https://repo.maven.apache.org/maven2/com/github/hiteshsondhi88/libffmpeg/FFmpegAndroid/0.3.2/FFmpegAndroid-0.3.2.pom
         Required by:
             project :app
    
    Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find com.github.hiteshsondhi88.libffmpeg:FFmpegAndroid:0.3.2.
    

    I tried to compile however the compiler immediatley rejected my app and refused to compile. I would have expected it to have immidiatley compiled into a apk.

    EDIT:

    Here is my build.gradle file

    plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
    }
    
    android {
        namespace 'com.icompilecodewithnowarnings.ffmpegthing'
        compileSdk 33
    
        defaultConfig {
            applicationId "com.icompilecodewithnowarnings.ffmpegthing"
            minSdk 26
            targetSdk 33
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        kotlinOptions {
            jvmTarget = '1.8'
        }
    }
    
    dependencies {
    
        implementation 'androidx.core:core-ktx:1.8.0'
        implementation 'androidx.appcompat:appcompat:1.4.1'
        implementation 'com.google.android.material:material:1.5.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
        implementation 'com.arthenica:mobile-ffmpeg-full:4.4'
        implementation files('src/main/java/musicg-1.4.2.0.jar')
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • FFMPEG Audio Not Working Using VideoShow Package

    17 février, par dev.skas

    I am creating a Node.js app that make video. I am facing some audio issue for each image, but my background sound is working

    async function generateVideo() {
      const images = [];
      for (let i = 0; i < conversation.length; i++) {
        images.push({
          path: `assets/image/conversation${i}.png`,
          duration: 5,
          caption: questions[i].question,
          audio: `assets/audio/conversation${i}.mp3`,
        }); // Show question for 5 sec
        images.push({
          path: `assets/image/reply${i}.png`,
          duration: 5,
          audio: `assets/audio/reply${i}.mp3`,
        }); // Show answer for 5 sec
      }
    
      const videoOptions = {
        fps: 30,
        loop: 5, // Each image duration
        transition: false,
        videoBitrate: 1024,
        videoCodec: "libx264",
        size: "1280x720",
        audioBitrate: "128k",
        format: "mp4",
        pixelFormat: "yuv420p",
      };
    
      videoshow(images, videoOptions)
        // .audio("assets/template/bgm.mp3")
        .save("video.mp4")
        .on("start", () => console.log("Generating video..."))
        .on("error", (err) => console.error("Error:", err))
        .on("end", () => console.log(" video created: video.mp4"));
    }

    Background sound is working. How i solve this issue. The FFmpeg build pack is downloaded from gyan.dev

  • ffmpeg unable to get duration/bitrate of remote gif

    17 février, par Peter Xia

    I'm trying to get the duration of a gif.

    The command ffmpeg -i https://cdn.7tv.app/emote/01F6MZGCNG000255K4X1K7NTHR/4x.gif

    gives Duration: N/A, start: 0.000000, bitrate: N/A

    However if i download the file and pass it in ffmpeg -i 4x.gif

    it gives: Duration: 00:00:07.92, start: 0.000000, bitrate: 1225 kb/s

    The issue seems limited only to gifs on 7tv site.

    • It works for other sites. (example: ffmpeg -i https://c.tenor.com/ULCY5B996-oAAAAd/tenor.gif).
    • It also works for other encodings of that image (exmaple ffmpeg -i https://cdn.7tv.app/emote/01F6MZGCNG000255K4X1K7NTHR/4x.avif)

    Here is the HTTP response header from 7tv site of that gif:

    HTTP/2 200 
    content-type: image/gif
    content-length: 1213725
    x-7tv-cache-hits: 37527
    x-7tv-cache: hit
    age: 228365
    cache-control: public, max-age=604800, s-maxage=86400, immutable
    alt-svc: h3=":443"; ma=2592000
    x-7tv-cdn-pod: cdn-ssprq
    x-7tv-cdn-node: cdn-1
    server: SevenTV
    vary: origin, access-control-request-method, access-control-request-headers
    access-control-allow-origin: *
    access-control-expose-headers: *
    date: Sun, 16 Feb 2025 20:47:28 GMT
    

    Can someone help me understand? Something spcecific to this site is causing ffmpeg to behave differently?

  • ffmpeg exit code 429496724 when opening file with {} in name

    16 février, par Holly Wilson

    I'm trying to write a program that will read the names of files in a directory, and parse them for info which it will then write into that file's metadata (seems pointless, I know, but it's more of a trial run for a larger project. If I can figure this out, then I'll be ready to move on to what I actually want to do). All of my filenames are formatted:

    Title, Article* - Subtitle* {Cut}* [Year] *if present

    The four test videos I'm using are titled:

    Test Video 1 [2000]

    Test Video 2, A [2000]

    Test Video 3 {Test Cut} [2000]

    Test Video 4 - The Testening [2000]

    The code seems to be working fine on videos 1, 2, & 4; but video 3 is causing me a lot of headache.

    //node C:\Users\User\Documents\Coding\Tools\testMDG.js
    const fs = require('fs');
    const path = require('path');
    const ffmpeg = require('fluent-ffmpeg');
    const async = require('async');
    const directory = path.normalize('F:\\Movies & TV\\Movies\\testDir');
    let x = 0;
    const fileArray = [];
    const succArray = [];
    const failArray = [];
    // Set the path to the ffmpeg executable
    ffmpeg.setFfmpegPath(path.normalize('C:\\ffmpeg\\bin\\ffmpeg.exe'));
    
    // Add this near the start of your script
    const tempDir = path.join(directory, 'temp');
    if (!fs.existsSync(tempDir)) {
        fs.mkdirSync(tempDir, { recursive: true });
    }
    
    const progresscsv = path.normalize('C:\\Users\\User\\Documents\\Coding\\Tools\\progress.csv');
    if (fs.existsSync(progresscsv)) {
        fs.unlinkSync(progresscsv);
    };
    
    const csvStream = fs.createWriteStream(progresscsv);
    csvStream.write('File Name,Status\n');
    
    const CONCURRENCY_LIMIT = 3; // Adjust based on your system capabilities
    
    // Add at the start of your script
    const processedFiles = new Set();
    
    function sanitizeFilePath(filePath) {
        return filePath.replace(/([{}])/g, '\\$1');
    }
    
    // Create a queue
    const queue = async.queue(async (task, callback) => {
        const { file, filePath, tempFilePath, movieMetadata } = task;
        try {
            await new Promise((resolve, reject) => {
                console.log(`ffmpeg reading: ${sanitizeFilePath(filePath)}`);
                ffmpeg(sanitizeFilePath(filePath))
                    .outputOptions([
                        '-y',
                        '-c', 'copy',
                        '-map', '0',
                        '-metadata', `title=${movieMetadata.title}`,
                        '-metadata', `subtitle=${movieMetadata.subtitle || ''}`,
                        '-metadata', `comment=${movieMetadata.cut || ''}`,
                        '-metadata', `year=${movieMetadata.year}`
                    ])
                    .on('error', (err) => reject(err))
                    .on('end', () => resolve())
                    .saveToFile(tempFilePath);
            });
            
            // Handle success
            console.log(`Successfully processed: ${file}`);
            succArray.push(file);
            // Only call callback once
            if (callback && typeof callback === 'function') {
                callback();
            }
        } catch (err) {
            // Handle error
            console.error(`Error processing ${file}: ${err.message}`);
            failArray.push(file);
            // Only call callback once with error
            if (callback && typeof callback === 'function') {
                callback(err);
            }
        }
    }, CONCURRENCY_LIMIT);
    
    fs.readdir(directory, (err, files) => {
        if (err) {
            console.error(`Error reading directory: ${err.message}`);
            return;
        }
        console.log(directory);
    
        // Filter for files only
        files = files.filter(file => fs.statSync(path.join(directory, file)).isFile());
        console.log(files);
    
        for (const file of files) {
            x++;
            const filePath = path.join(directory, file);
            let desort = file.replace(/(.*),\s(the\s|an\s|a\s)/i, '$2'+'$1 ') || file;
            
            // Create task object for queue
            const task = {
                file,
                filePath: filePath,
                tempFilePath: path.join(directory, 'temp', `temp_${x}_${path.parse(file).name
                    .replace(/[^a-zA-Z0-9]/g, '_')}${path.extname(file)}`),
                movieMetadata: {
                    title: desort.replace(/(\s[\-\{\[].*)/gi, ``),
                    subtitle: desort.includes('-') ? desort.replace(/(.*)\-\s(.*?)[\{\[].*/gi, '$2') : null,
                    cut: desort.includes('{') ? desort.replace(/.*\{(.*)\}.*/gi, '$1') : null,
                    year: desort.replace(/.*\[(.*)\].*/gi, '$1')
                }
            };
            
            // Add to processing queue
            queue.push(task, (err) => {
                if (!processedFiles.has(task.file)) {
                    processedFiles.add(task.file);
                    if (err) {
                        csvStream.write(`${task.file},Failed\n`);
                    } else {
                        csvStream.write(`${task.file},Processed\n`);
                    }
                }
            });
        }
    });
    
    // Add queue completion handler
    queue.drain(() => {
        console.log('All files have been processed');
        console.log(`Success: ${succArray.length} files: ${succArray}`);
        console.log(`Failed: ${failArray.length} files: ${failArray}`);
    });
    
    //node C:\Users\User\Documents\Coding\Tools\testMDG.js
    

    And the console is logging:

    PS C:\Users\User> node C:\Users\User\Documents\Coding\Tools\testMDG.js
    F:\Movies & TV\Movies\testDir
    [
      'Test Video 1 [2020].mp4',
      'Test Video 2, A [2020].mp4',
      'Test Video 3 {Test Cut} [2020].mp4',
      'Test Video 4 - The Testening [2020].mp4'
    ]
    ffmpeg reading: F:\Movies & TV\Movies\testDir\Test Video 1 [2020].mp4
    ffmpeg reading: F:\Movies & TV\Movies\testDir\Test Video 2, A [2020].mp4
    ffmpeg reading: F:\Movies & TV\Movies\testDir\Test Video 3 \{Test Cut\} [2020].mp4
    Error processing Test Video 3 {Test Cut} [2020].mp4: ffmpeg exited with code 4294967294: Error opening input file F:\Movies & TV\Movies\testDir\Test Video 3 \{Test Cut\} [2020].mp4.
    Error opening input files: No such file or directory
    
    ffmpeg reading: F:\Movies & TV\Movies\testDir\Test Video 4 - The Testening [2020].mp4
    Successfully processed: Test Video 1 [2020].mp4
    Successfully processed: Test Video 2, A [2020].mp4
    Successfully processed: Test Video 4 - The Testening [2020].mp4
    All files have been processed
    Success: 3 files: Test Video 1 [2020].mp4,Test Video 2, A [2020].mp4,Test Video 4 - The Testening [2020].mp4
    Failed: 1 files: Test Video 3 {Test Cut} [2020].mp4
    

    I've tried so many different solutions in the sanitizeFilePath function. Escaping the {} characters (as included below), escaping all non-alphanumeric characters, putting the filepath in quotes, etc. VSCode's CoPilot is just pulling me round in circles, suggesting solutions I've already tried.

  • How to seamlessly concatenate multiple Opus files together without popping sound ?

    16 février, par Gurdie Derilus

    I have a large PCM file that I've split into N chunks (N being the # of threads), and I encode them in parallel into Opus files with FFmpeg.

    Note: All PCM files are 16-bit Little Endian, 2 channels, 48000 sample rate.

    I then concatenate the Opus files using FFmpeg's demuxer, but I can hear an audible pop sound between each segment.

    Opening this sample file in Audacity reveals the issue: Notice the introduced pops in opus

    I created a simple and short Golang project on Github with a sample PCM file for easy testing. Note, not production code, so obviously not following any best practices here.

    #1, I suspected the pops might've been introduced while parallel encoding each PCM file to Opus files. This, however, wasn't the case. Concatted Opus files vs Separate Opus files image.

    #2, using the concat filter works, however it reencodes the files, which is not doable in my case as it's too slow (these files can & do reach up to an hour). I know Opus files are chainable, so I can't imagine why they don't work flawlessly.

    #3, I heard that Opus has a 20ms frame size, so I split the file against that frame size, but this made no difference.

    chunkSize := largePcmFileStat.Size() / int64(runtime.GOMAXPROCS(0))
    chunkSize = int64(roundUpToNearestMultiple(float64(chunkSize), 4))
    

    The entire sample looks like this:

    package main
    
    import (
        "context"
        "fmt"
        "io"
        "log"
        "os"
    )
    
    func main() {
        // Grab large PCM file
        largePcmFile, err := os.Open("files/full_raw.pcm")
        if err != nil {
            log.Fatalln(err)
        }
    
        // Split into 2 chunks
        ByteRate := 2
        SampleRate := 48000
        Channels := 2
        Seconds := 20
        chunkSize := Seconds * Channels * SampleRate * ByteRate
    
        file1, err := encodePcmToOpus(context.TODO(), io.LimitReader(largePcmFile, int64(chunkSize)))
        if err != nil {
            log.Fatalln(err)
        }
    
        file2, err := encodePcmToOpus(context.TODO(), io.LimitReader(largePcmFile, int64(chunkSize)))
        if err != nil {
            log.Fatalln(err)
        }
    
        fmt.Println("Check if these play with no defects:", file1)
        fmt.Println("file1:", file1)
        fmt.Println("file2:", file2)
        fmt.Println()
    
        concatFile, err := concatOpusFiles(context.TODO(), []string{file1, file2})
        if err != nil {
            log.Fatalln(err)
        }
    
        fmt.Println("concatted file:", concatFile.Name())
    }