mirror of
https://github.com/samsonjs/SJSAssetExportSession.git
synced 2026-04-27 14:57:46 +00:00
Merge pull request #2 from samsonjs/spatial-audio
Drop spatial audio tracks to fix encoding iPhone 16 videos
This commit is contained in:
commit
1e3651ae0d
5 changed files with 40 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ let package = Package(
|
||||||
.process("Resources/test-720p-h264-24fps.mov"),
|
.process("Resources/test-720p-h264-24fps.mov"),
|
||||||
.process("Resources/test-no-audio.mp4"),
|
.process("Resources/test-no-audio.mp4"),
|
||||||
.process("Resources/test-no-video.m4a"),
|
.process("Resources/test-no-video.m4a"),
|
||||||
|
.process("Resources/test-spatial-audio.mov"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
18
Sources/SJSAssetExportSession/Array+Extensions.swift
Normal file
18
Sources/SJSAssetExportSession/Array+Extensions.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -70,12 +70,16 @@ actor SampleWriter {
|
||||||
writer.shouldOptimizeForNetworkUse = optimizeForNetworkUse
|
writer.shouldOptimizeForNetworkUse = optimizeForNetworkUse
|
||||||
writer.metadata = metadata
|
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)
|
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.
|
// Audio is optional so only validate output settings when it's applicable.
|
||||||
if !audioTracks.isEmpty {
|
if !audioTracks.isEmpty {
|
||||||
try Self.validateAudio(outputSettings: audioOutputSettings, writer: writer)
|
try Self.validateAudio(outputSettings: audioOutputSettings, writer: writer)
|
||||||
}
|
}
|
||||||
let videoTracks = try await asset.loadTracks(withMediaType: .video)
|
let videoTracks = try await asset.loadTracks(withMediaType: .video)
|
||||||
|
.filterAsync { try await $0.load(.isEnabled) }
|
||||||
guard !videoTracks.isEmpty else { throw Error.setupFailure(.videoTracksEmpty) }
|
guard !videoTracks.isEmpty else { throw Error.setupFailure(.videoTracksEmpty) }
|
||||||
try Self.validateVideo(outputSettings: videoOutputSettings, writer: writer)
|
try Self.validateVideo(outputSettings: videoOutputSettings, writer: writer)
|
||||||
Self.warnAboutMismatchedVideoSize(
|
Self.warnAboutMismatchedVideoSize(
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -357,4 +357,21 @@ final class ExportSessionTests {
|
||||||
})?.load(.value) as? NSString
|
})?.load(.value) as? NSString
|
||||||
#expect(commonMetadataValue == "+48.50176+123.34368/")
|
#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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue