SwiftFFmpeg Documentation

repository·master·Indexed 20 days ago

https://github.com/sunlubo/swiftffmpeg

A Swift wrapper for the FFmpeg API providing a Swift-friendly interface for media processing tasks such as decoding and stream manipulation. Requires FFmpeg 7.1 or higher.

Tokens
966
Snippets
3
Records
3
Agent score
21%

What's inside SwiftFFmpeg

  1. Add SwiftFFmpeg to Swift Package Manager

    master

    To use SwiftFFmpeg in your project, add it to your Package.swift file's dependencies array. Note that the API is currently in development and subject to change.

    dependencies: [
        .package(url: "https://github.com/sunlubo/SwiftFFmpeg.git", from: "1.0.0")
    ]
  2. Example: Decoding video frames with SwiftFFmpeg

    master

    This example demonstrates the standard workflow for decoding a video file:

    1. Initialize an AVFormatContext from a file URL.
    2. Call findStreamInfo() to populate stream information.
    3. Locate the video stream and find the appropriate decoder using AVCodec.findDecoderById.
    4. Initialize an AVCodecContext and open the codec.
    5. Iterate through packets using readFrame(into:).
    6. Send packets to the codec via sendPacket(_:) and receive decoded frames via receiveFrame(_:).

    Note: Ensure you call unref() on AVPacket and AVFrame to manage memory correctly.

    import Foundation
    import SwiftFFmpeg
    
    if CommandLine.argc < 2 {
        print("Usage: \(CommandLine.arguments[0]) <input file>")
        exit(1)
    }
    let input = CommandLine.arguments[1]
    
    let fmtCtx = try AVFormatContext(url: input)
    try fmtCtx.findStreamInfo()
    
    fmtCtx.dumpFormat(isOutput: false)
    
    guard let stream = fmtCtx.videoStream else {
        fatalError("No video stream.")
    }
    guard let codec = AVCodec.findDecoderById(stream.codecParameters.codecId) else {
        fatalError("Codec not found.")
    }
    let codecCtx = AVCodecContext(codec: codec)
    codecCtx.setParameters(stream.codecParameters)
    try codecCtx.openCodec()
    
    let pkt = AVPacket()
    let frame = AVFrame()
    
    while let _ = try? fmtCtx.readFrame(into: pkt) {
        defer { pkt.unref() }
    
        if pkt.streamIndex != stream.index {
            continue
        }
    
        try codecCtx.sendPacket(pkt)
    
        while true {
            do {
                try codecCtx.receiveFrame(frame)
            } catch let err as AVError where err == .tryAgain || err == .eof {
                break
            }
    
            let str = String(
                format: "Frame %3d (type=%@, size=%5d bytes) pts %4lld key_frame %d",
                codecCtx.frameNumber,
                frame.pictureType.description,
                frame.pktSize,
                frame.pts,
                frame.isKeyFrame
            )
            print(str)
    
            frame.unref()
        }
    }
    
    print("Done.")