67 lines
2.1 KiB
Swift
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()
|
|
}
|
|
}
|