Thank you for your work and the MediaToolSwift. It helps me a lot to transcode videos, user import into my app.
As it turns out I have a use-case where the check for a passthrough audio track works different, as a user would expect it.
Sometime, user will import a video that has an audio track already encoded with aac
and a bitrate on 32kbit/s. While there is a limitation on the Apple frameworks (does not allow a bitrate lower than 64kbit/s) it seems appropriate to passthrough the source audio stream and skip the compression.
In the method initAudio()
in Video.swift
there is a check to compare the audio settings.
// Compare source audio settings with output to possibly skip the compression
let defaultSettings = CompressionAudioSettings()
if audioFormatID == codec.formatId,
audioSettings.bitrate == defaultSettings.bitrate,
!((audioFormatID == kAudioFormatMPEG4AAC || audioFormatID == kAudioFormatFLAC)
&& audioSettings.quality != defaultSettings.quality),
audioSettings.sampleRate == defaultSettings.sampleRate
{
variables.hasChanges = false
}
The thing is, that the check for audioFormatID == kAudioFormatMPEG4AAC
will force MediaToolSwift to re-encode the audio track, even the source is already aac
but has a lower bit rate than audioSettings.bitrate
.
Also, the check for audioSettings.bitrate == defaultSettings.bitrate
will (almost every time) fail as default.bitrate
is .auto
and in most use cases a user will give a bitrate value.
For myself I use something like that as a work around:
// To avoid re-encoding if source has a lower audio bitrate than selected target audio bitrate, check it.
let sourceAudioBitrate = audioTrack!.estimatedDataRate
let dummySourceAudioSettings = CompressionAudioSettings(codec: audioSettings.codec,
bitrate: .value(Int(sourceAudioBitrate)),
quality: audioSettings.quality,
sampleRate: audioSettings.sampleRate)
if audioFormatID == codec.formatId,
dummySourceAudioSettings.bitrate <= audioSettings.bitrate,
audioSettings.quality == defaultSettings.quality,
audioSettings.sampleRate == defaultSettings.sampleRate
{
variables.hasChanges = false
sourceFormatHint = audioDescription
}
Be aware, that sourceFormatHint = audioDescription
is needed in my case.
In AudioBitrate.swift
I added an Equatable for <=
, too.
public static func <= (lhs: CompressionAudioBitrate, rhs: CompressionAudioBitrate) -> Bool {
switch (lhs, rhs) {
case (.auto, .auto):
return false
case (.value(let lhsValue), .value(let rhsValue)):
return lhsValue <= rhsValue
default:
return false
}
}
Edit: correct check is dummySourceAudioSettings.bitrate <= audioSettings.bitrate,