Merge pull request #2 from samsonjs/spatial-audio

Drop spatial audio tracks to fix encoding iPhone 16 videos
This commit is contained in:
Sami Samhuri 2024-10-04 08:29:44 -07:00 committed by GitHub
commit 1e3651ae0d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 0 deletions

View file

@ -23,6 +23,7 @@ let package = Package(
.process("Resources/test-720p-h264-24fps.mov"),
.process("Resources/test-no-audio.mp4"),
.process("Resources/test-no-video.m4a"),
.process("Resources/test-spatial-audio.mov"),
]
),
]

View file

@ -0,0 +1,18 @@
//
// Array+Extensions.swift
// SJSAssetExportSession
//
// Created by Sami Samhuri on 2024-10-04.
//
extension Array {
func filterAsync(_ isIncluded: (Element) async throws -> Bool) async rethrows -> [Element] {
var result: [Element] = []
for element in self {
if try await isIncluded(element) {
result.append(element)
}
}
return result
}
}

View file

@ -70,12 +70,16 @@ actor SampleWriter {
writer.shouldOptimizeForNetworkUse = optimizeForNetworkUse
writer.metadata = metadata
// Filter out disabled tracks to avoid problems encoding spatial audio. Ideally this would
// preserve track groups and make that all configurable.
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
.filterAsync { try await $0.load(.isEnabled) }
// Audio is optional so only validate output settings when it's applicable.
if !audioTracks.isEmpty {
try Self.validateAudio(outputSettings: audioOutputSettings, writer: writer)
}
let videoTracks = try await asset.loadTracks(withMediaType: .video)
.filterAsync { try await $0.load(.isEnabled) }
guard !videoTracks.isEmpty else { throw Error.setupFailure(.videoTracksEmpty) }
try Self.validateVideo(outputSettings: videoOutputSettings, writer: writer)
Self.warnAboutMismatchedVideoSize(

View file

@ -357,4 +357,21 @@ final class ExportSessionTests {
})?.load(.value) as? NSString
#expect(commonMetadataValue == "+48.50176+123.34368/")
}
@Test func test_works_with_spatial_audio_track() async throws {
let sourceURL = resourceURL(named: "test-spatial-audio.mov")
let destinationURL = makeTemporaryURL()
let subject = ExportSession()
try await subject.export(
asset: makeAsset(url: sourceURL),
video: .codec(.h264, size: CGSize(width: 720, height: 1280)),
to: destinationURL.url,
as: .mp4
)
let exportedAsset = AVURLAsset(url: destinationURL.url)
let audioTracks = try await exportedAsset.loadTracks(withMediaType: .audio)
#expect(audioTracks.count == 1)
}
}