Files
2020-07-23 15:32:47 +08:00

67 lines
2.1 KiB
Swift

//
// split_stream.swift
// SwiftFFmpegExamples
//
// Created by sunlubo on 2019/1/19.
//
import SwiftFFmpeg
private func makeMuxer(stream: AVStream) throws -> (AVFormatContext, AVStream) {
let input = CommandLine.arguments[2]
let output =
"\(input[..<(input.firstIndex(of: ".") ?? input.endIndex)])_\(stream.index).\(stream.codecParameters.codecId.name)"
print(output)
let muxer = try AVFormatContext(format: nil, filename: String(output))
guard let ostream = muxer.addStream() else {
fatalError("Failed allocating output stream.")
}
ostream.codecParameters.copy(from: stream.codecParameters)
ostream.codecParameters.codecTag = 0
if !muxer.outputFormat!.flags.contains(.noFile) {
try muxer.openOutput(url: output, flags: .write)
}
return (muxer, ostream)
}
func split_stream() throws {
if CommandLine.argc < 3 {
print("Usage: \(CommandLine.arguments[0]) \(CommandLine.arguments[1]) input_file")
return
}
let fmtCtx = try AVFormatContext(url: CommandLine.arguments[2])
try fmtCtx.findStreamInfo()
fmtCtx.dumpFormat(isOutput: false)
var streamMapping = [Int: (AVFormatContext, AVStream)]()
for istream in fmtCtx.streams where istream.mediaType == .audio || istream.mediaType == .video {
streamMapping[istream.index] = try makeMuxer(stream: istream)
}
for (_, (muxer, _)) in streamMapping {
try muxer.writeHeader()
}
let pkt = AVPacket()
while let _ = try? fmtCtx.readFrame(into: pkt) {
if let (muxer, ostream) = streamMapping[pkt.streamIndex] {
let istream = fmtCtx.streams[pkt.streamIndex]
pkt.pts = AVMath.rescale(
pkt.pts, istream.timebase, ostream.timebase, rounding: .nearInf, passMinMax: true)
pkt.dts = AVMath.rescale(
pkt.dts, istream.timebase, ostream.timebase, rounding: .nearInf, passMinMax: true)
pkt.duration = AVMath.rescale(pkt.duration, istream.timebase, ostream.timebase)
pkt.position = -1
pkt.streamIndex = ostream.index
try muxer.interleavedWriteFrame(pkt)
}
pkt.unref()
}
for (_, (muxer, _)) in streamMapping {
try muxer.writeTrailer()
}
}