Splitting and Processing Large Files

Welcome back! In our previous lessons, we've explored using basic transcribing techniques with OpenAI's Whisper API, as well as calculating the media duration using FFmpeg. Today, we'll shift our focus to transcribing large files with OpenAI Whisper and FFmpeg. Managing large audio or video files by splitting them into manageable pieces ensures that tasks like transcription can be performed efficiently and without errors. This lesson will empower you to handle these files smoothly, leveraging FFmpeg's capabilities.

Understanding Transcribing Large Files

OpenAI Whisper has a file size limitation of 25 MB, which poses a challenge when attempting to transcribe large audio or video files. To work around this constraint, we need a method to divide these large files into smaller, manageable chunks that can be processed sequentially. Our strategy involves leveraging FFmpeg's capabilities to split the files into segments that fall within the permissible size limit. This will ensure compatibility with OpenAI Whisper while maintaining the quality and integrity of the original content. By breaking down large files, we facilitate efficient transcription, allowing for smooth and accurate processing of each smaller segment.

Using FFmpeg to Split Media Files: Media Duration

Let's consider TypeScript code to achieve this, ensuring all steps are easily comprehensible. First, let's revisit how we retrieve the media's length using FFmpeg:

This section of the code employs ffprobe to determine an audio file's duration. ffprobe is a component of FFmpeg that fetches file data without altering it. The command is carefully structured to extract only the duration, allowing us to calculate how to split the file accordingly. In TypeScript, we use Node.js's child_process.execSync to run the command synchronously and capture its output.

Using FFmpeg to Split Media Files: Streaming FFmpeg's Output

Now, let's implement one more helper function. Splitting a media file into chunks is a time-consuming process, and FFmpeg will produce its logs as a stream — they will iteratively appear as it keeps processing the file. In order for us to process that efficiently, we should implement a way to stream these logs to the console in TypeScript:

This helper function allows us to run commands and stream outputs in real-time. To do this in TypeScript, we set up event listeners for the stdout and stderr streams. By using child_process.spawn, we create a child process and capture its output asynchronously, ensuring you keep track of the progress during long operations, a critical feature when managing large files.

Using FFmpeg to Split Media Files: Splitting Files into Chunks

The process of splitting media files into smaller chunks involves key FFmpeg commands that work together to extract segments without re-encoding. Let's break down the TypeScript code to see how it operates:

Code Explanation:

  1. Initialize Variables:

    • We first determine the duration of the media file using the helper getAudioDuration function.
    • The fileSize is retrieved using Node.js's fs.statSync(filePath).size to calculate the proper chunk duration that fits within the specified chunkSizeMb limit (which is by default 20Mb).
  2. Calculate Chunks:

    • chunkDuration uses the ratio of chunkSizeMb to fileSize multiplied by the duration to find how long each chunk should be.
    • numChunks calculates the total number of chunks required by dividing the full duration by chunkDuration and rounding up.
  3. Create Each Chunk:

    • A loop iterates over each chunk, calculating the startTime for each segment.
    • Then, we create a unique temporary file path using Node.js's tmpdir() and the crypto module to generate a random hex string.
  4. FFmpeg Command:

    • -i specifies the input file.
    • -ss sets the start time for each chunk.
    • -t sets the duration for each chunk.
    • -c copy ensures content is copied directly without re-encoding, preserving quality and improving efficiency.
    • -y automatically overwrites existing output files without user confirmation.
  5. Run Command and Store Chunks:

    • runCommandWithOutput asynchronously executes the FFmpeg command, streaming progress to keep the user informed.
    • Each generated temporary file is appended to the chunks array, which is later returned for further processing.

This approach systematically breaks down large files into smaller, manageable pieces using FFmpeg's powerful media handling capabilities.

Checking Yourself: Executing the Media File Split

Running the code in a TypeScript application will look something like this:

When executed, you'll see output similar to this:

The sample_video.mp4 video file size is around 2Mb, so splitting it with chunkSizeMb set to 1 produces 2 chunks of approximately 1 Mb each, both of which are properly extracted with FFmpeg and saved as separate temporary files.

Lesson Summary

Congratulations on mastering the process of splitting large media files using FFmpeg in TypeScript! In this lesson, you've learned how to leverage FFmpeg's capabilities to efficiently break down large files into smaller, manageable chunks. By understanding the intricacies of file handling with Node.js and TypeScript, you can now enhance file operations, reduce memory overhead, and enable parallel processing for improved performance, all while maintaining content quality. You're now well-equipped to tackle large-scale multimedia tasks with confidence and precision!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal