mirror of
https://github.com/samsonjs/SJSAssetExportSession.git
synced 2026-03-25 08:45:50 +00:00
Make SampleWriter.init nonisolated so it can load tracks
This commit is contained in:
parent
996251cfde
commit
8f049aed95
5 changed files with 19 additions and 19 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
7B7AE3092C36615700DB7391 /* SampleWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7AE3082C36615700DB7391 /* SampleWriter.swift */; };
|
||||
7B9867982C6AF57C001353BC /* AVAsset+sending.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC8B2C3BB0180090B757 /* AVAsset+sending.swift */; };
|
||||
7B9BC00E2C305D2C00C160C2 /* SJSAssetExportSession.docc in Sources */ = {isa = PBXBuildFile; fileRef = 7B9BC00D2C305D2C00C160C2 /* SJSAssetExportSession.docc */; };
|
||||
7B9BC0142C305D2C00C160C2 /* SJSAssetExportSession.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B9BC0092C305D2C00C160C2 /* SJSAssetExportSession.framework */; };
|
||||
7B9BC0192C305D2C00C160C2 /* SJSAssetExportSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B9BC0182C305D2C00C160C2 /* SJSAssetExportSessionTests.swift */; };
|
||||
|
|
@ -16,7 +17,6 @@
|
|||
7BC5FC772C3B8C5A0090B757 /* SendableWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC762C3B8C5A0090B757 /* SendableWrapper.swift */; };
|
||||
7BC5FC792C3B90F70090B757 /* AutoDestructingURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC782C3B90F70090B757 /* AutoDestructingURL.swift */; };
|
||||
7BC5FC8A2C3BAA150090B757 /* ExportSession+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC892C3BAA150090B757 /* ExportSession+Error.swift */; };
|
||||
7BC5FC8C2C3BB0180090B757 /* AVAsset+sending.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC8B2C3BB0180090B757 /* AVAsset+sending.swift */; };
|
||||
7BC5FC902C3BB2030090B757 /* AudioOutputSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC8F2C3BB2030090B757 /* AudioOutputSettings.swift */; };
|
||||
7BC5FC922C3BB4BD0090B757 /* VideoOutputSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC912C3BB4BD0090B757 /* VideoOutputSettings.swift */; };
|
||||
7BC5FC942C3BC3AD0090B757 /* CMTime+seconds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC5FC932C3BC3AD0090B757 /* CMTime+seconds.swift */; };
|
||||
|
|
@ -95,7 +95,6 @@
|
|||
children = (
|
||||
7BC5FC8F2C3BB2030090B757 /* AudioOutputSettings.swift */,
|
||||
7BC5FC912C3BB4BD0090B757 /* VideoOutputSettings.swift */,
|
||||
7BC5FC8B2C3BB0180090B757 /* AVAsset+sending.swift */,
|
||||
7BC5FC932C3BC3AD0090B757 /* CMTime+seconds.swift */,
|
||||
7B9BC0272C30612C00C160C2 /* ExportSession.swift */,
|
||||
7BC5FC892C3BAA150090B757 /* ExportSession+Error.swift */,
|
||||
|
|
@ -110,6 +109,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
7BC5FC782C3B90F70090B757 /* AutoDestructingURL.swift */,
|
||||
7BC5FC8B2C3BB0180090B757 /* AVAsset+sending.swift */,
|
||||
7BC5FC812C3B9E3D0090B757 /* Resources */,
|
||||
7BC5FC762C3B8C5A0090B757 /* SendableWrapper.swift */,
|
||||
7B9BC0182C305D2C00C160C2 /* SJSAssetExportSessionTests.swift */,
|
||||
|
|
@ -233,7 +233,6 @@
|
|||
7B7AE3092C36615700DB7391 /* SampleWriter.swift in Sources */,
|
||||
7BC5FC902C3BB2030090B757 /* AudioOutputSettings.swift in Sources */,
|
||||
7B9BC0282C30612C00C160C2 /* ExportSession.swift in Sources */,
|
||||
7BC5FC8C2C3BB0180090B757 /* AVAsset+sending.swift in Sources */,
|
||||
7BC5FC922C3BB4BD0090B757 /* VideoOutputSettings.swift in Sources */,
|
||||
7B9BC00E2C305D2C00C160C2 /* SJSAssetExportSession.docc in Sources */,
|
||||
7BC5FC8A2C3BAA150090B757 /* ExportSession+Error.swift in Sources */,
|
||||
|
|
@ -246,6 +245,7 @@
|
|||
files = (
|
||||
7B9BC0192C305D2C00C160C2 /* SJSAssetExportSessionTests.swift in Sources */,
|
||||
7BC5FC792C3B90F70090B757 /* AutoDestructingURL.swift in Sources */,
|
||||
7B9867982C6AF57C001353BC /* AVAsset+sending.swift in Sources */,
|
||||
7BC5FC772C3B8C5A0090B757 /* SendableWrapper.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
|||
|
|
@ -45,12 +45,12 @@ actor SampleWriter {
|
|||
private var videoInput: AVAssetWriterInput?
|
||||
private var isCancelled = false
|
||||
|
||||
init(
|
||||
nonisolated init(
|
||||
asset: sending AVAsset,
|
||||
audioOutputSettings: sending [String: (any Sendable)],
|
||||
audioMix: AVAudioMix?,
|
||||
audioMix: sending AVAudioMix?,
|
||||
videoOutputSettings: sending [String: (any Sendable)],
|
||||
videoComposition: AVVideoComposition,
|
||||
videoComposition: sending AVVideoComposition,
|
||||
timeRange: CMTimeRange? = nil,
|
||||
optimizeForNetworkUse: Bool = false,
|
||||
outputURL: URL,
|
||||
|
|
@ -67,10 +67,14 @@ actor SampleWriter {
|
|||
let writer = try AVAssetWriter(outputURL: outputURL, fileType: fileType)
|
||||
writer.shouldOptimizeForNetworkUse = optimizeForNetworkUse
|
||||
|
||||
let audioTracks = try await asset.sendTracks(withMediaType: .audio)
|
||||
try Self.validateAudio(tracks: audioTracks, outputSettings: audioOutputSettings, writer: writer)
|
||||
let videoTracks = try await asset.sendTracks(withMediaType: .video)
|
||||
try Self.validateVideo(tracks: videoTracks, outputSettings: videoOutputSettings, writer: writer)
|
||||
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
|
||||
// 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)
|
||||
guard !videoTracks.isEmpty else { throw Error.setupFailure(.videoTracksEmpty) }
|
||||
try Self.validateVideo(outputSettings: videoOutputSettings, writer: writer)
|
||||
Self.warnAboutMismatchedVideoSize(
|
||||
renderSize: videoComposition.renderSize,
|
||||
settings: videoOutputSettings
|
||||
|
|
@ -85,8 +89,8 @@ actor SampleWriter {
|
|||
self.duration = duration
|
||||
self.timeRange = timeRange ?? CMTimeRange(start: .zero, duration: duration)
|
||||
|
||||
try setUpAudio(audioTracks: audioTracks)
|
||||
try setUpVideo(videoTracks: videoTracks)
|
||||
try await setUpAudio(audioTracks: audioTracks)
|
||||
try await setUpVideo(videoTracks: videoTracks)
|
||||
}
|
||||
|
||||
func writeSamples() async throws {
|
||||
|
|
@ -281,11 +285,9 @@ actor SampleWriter {
|
|||
// MARK: Input validation
|
||||
|
||||
private static func validateAudio(
|
||||
tracks: [AVAssetTrack],
|
||||
outputSettings: [String: any Sendable],
|
||||
writer: AVAssetWriter
|
||||
) throws {
|
||||
guard !tracks.isEmpty else { return } // Audio is optional so this isn't a failure.
|
||||
guard !outputSettings.isEmpty else { throw Error.setupFailure(.audioSettingsEmpty) }
|
||||
guard writer.canApply(outputSettings: outputSettings, forMediaType: .audio) else {
|
||||
throw Error.setupFailure(.audioSettingsInvalid)
|
||||
|
|
@ -293,11 +295,9 @@ actor SampleWriter {
|
|||
}
|
||||
|
||||
private static func validateVideo(
|
||||
tracks: [AVAssetTrack],
|
||||
outputSettings: [String: any Sendable],
|
||||
writer: AVAssetWriter
|
||||
) throws {
|
||||
guard !tracks.isEmpty else { throw Error.setupFailure(.videoTracksEmpty) }
|
||||
guard writer.canApply(outputSettings: outputSettings, forMediaType: .video) else {
|
||||
throw Error.setupFailure(.videoSettingsInvalid)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Sami Samhuri on 2024-07-07.
|
||||
//
|
||||
|
||||
public import AVFoundation
|
||||
import AVFoundation
|
||||
|
||||
public struct VideoOutputSettings {
|
||||
public enum H264Profile {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// AVAsset+sending.swift
|
||||
// SJSAssetExportSession
|
||||
// SJSAssetExportSessionTests
|
||||
//
|
||||
// Created by Sami Samhuri on 2024-07-07.
|
||||
//
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
// Created by Sami Samhuri on 2024-06-29.
|
||||
//
|
||||
|
||||
import AVFoundation
|
||||
internal import AVFoundation
|
||||
@testable import SJSAssetExportSession
|
||||
import Testing
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue