Skip to content

Instantly share code, notes, and snippets.

View samsonjs's full-sized avatar

Sami Samhuri samsonjs

View GitHub Profile
@samsonjs
samsonjs / log.txt
Created September 27, 2024 17:41
AVFoundation error on spatial videos
Failed to append audio sample buffer CMSampleBuffer 0x1360948c0 retainCount: 3 allocator: 0x1fc343380
invalid = NO
dataReady = YES
makeDataReadyCallback = 0x0
makeDataReadyRefcon = 0x0
formatDescription = <CMAudioFormatDescription 0x30353c420 [0x1fc343380]> {
mediaType:'soun'
mediaSubType:'lpcm'
mediaSpecific: {
ASBD: {
@samsonjs
samsonjs / ContentView.swift
Created September 17, 2024 02:25
FB15150266: PhotosPicker label closure issue with Xcode 16.0
import PhotosUI
import SwiftUI
enum SFSymbol: String {
case ant
}
extension Label where Title == Text, Icon == Image {
init(_ titleKey: LocalizedStringKey, systemSymbol: SFSymbol) {
self.init(titleKey, systemImage: systemSymbol.rawValue)
@samsonjs
samsonjs / gross.swift
Last active September 14, 2024 20:27
Work-around for nonisolated PhotosPicker initializer in Xcode 16.0 RC
import PhotosUI
import SwiftUI
private final class SendableWrapper<T>: @unchecked Sendable {
private var unsafeValue: T
private let lock = NSLock()
var value: T {
get {
@samsonjs
samsonjs / SampleWriter.swift
Created July 11, 2024 06:27
Task cancellation in a dispatch queue world of AVAssetWriterInputs
actor SampleWriter {
// ...
var isCancelled = false
// ...
func cancel() async {
isCancelled = true
}
private func encodeAudioTracks() async {
@samsonjs
samsonjs / ExportSession.swift
Created July 8, 2024 15:54
Attempting to send non-Sendable AVFoundation types in a safe way
public import AVFoundation
struct UniqueRef<Value>: ~Copyable, @unchecked Sendable {
private let lock = NSLock()
private var unsafeValue: Value?
init(value: sending Value) {
self.unsafeValue = value
}
@samsonjs
samsonjs / ContentView.swift
Created July 2, 2024 21:22
How to fix a Swift 6 warning: "Sending main actor-isolated value of type 'WebAuthenticationSession' with later accesses to nonisolated context risks causing data races; this is an error in the Swift 6 language mode"
// https://iosdev.space/@andy/112714337582288785
import AuthenticationServices
import SwiftUI
struct ContentView: View {
@State var url = URL(string: "https://example.net")!
@Environment(\.webAuthenticationSession) var webAuthenticationSession
@samsonjs
samsonjs / VFAExportSession.swift
Last active June 29, 2024 05:10
Exploring possible modern APIs for something like AVAssetExportSession
// Old way
let session = VFAExportSession(asset: asset)
session.timeRange = CMTimeRange(start: .seconds(1), duration: .seconds(3))
session.audioMix = audioMix
session.audioOutputConfiguration = [
AVFormatIDKey: kAudioFormatMPEG4AAC,
AVNumberOfChannelsKey: NSNumber(value: 2),
AVSampleRateKey: NSNumber(value: 44_100.0),
]
session.videoComposition = videoComposition
@samsonjs
samsonjs / SendableWrapper.swift
Last active November 3, 2024 13:48
See https://github.com/samsonjs/SJSAssetExportSession — Exporting videos with AVFoundation in the strict concurrency world of Swift 6
//
// Created by Sami Samhuri on 2024-06-26.
//
import Foundation
final class SendableWrapper<T>: @unchecked Sendable {
private var unsafeValue: T
private let lock = NSLock()
@samsonjs
samsonjs / Tracks.swift
Last active June 24, 2024 15:20
FB14035001: Tracks loaded from an AVAsset should be marked `sending` to be used from actor-isolated contexts
import AVFoundation
/*
* In Swift 6 it’s not currently possible to directly load tracks from an AVAsset using a method like
* AVAsset.loadTracks(withMediaType:) from an actor-isolated context, because AVAssetTrack isn’t Sendable. Given
* that many AVFoundation types are not sendable / thread-safe it’s tempting to use an actor to work with
* compositions and that currently requires some work-arounds that shouldn’t be necessary and may not be obvious
* to everyone.
*/
@samsonjs
samsonjs / SendableWrapper.swift
Last active June 22, 2024 16:46
SyncState isolation example
final class SendableWrapper<T>: @unchecked Sendable {
private var unsafeValue: T
private let lock = NSLock()
var value: T {
get {
lock.withLock { unsafeValue }
}
set {