一个用于 FFmpeg API 的 Swift 封装。
注意:SwiftFFmpeg 仍在开发中,API 不保证稳定。它可能会在没有警告的情况下发生变化。
在使用此库之前,您应该安装 FFmpeg(需要 FFmpeg 7.1 或更高版本)。在 macOS 上,您可以
brew install ffmpeg
SwiftFFmpeg 主要使用 SwiftPM 作为其构建工具,因此我们也建议您使用它。如果您想在您自己的项目中依赖 SwiftFFmpeg,只需将一个 dependencies
子句添加到您的 Package.swift
中即可。
dependencies: [
.package(url: "https://github.com/sunlubo/SwiftFFmpeg.git", from: "1.0.0")
]
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.")