From bed5866de3e0fdeeff2df196ea7379092e236b89 Mon Sep 17 00:00:00 2001 From: ryanda9910 Date: Fri, 19 Jun 2026 13:01:14 +0700 Subject: [PATCH 1/2] feat(recording): make iOS export quality configurable Wire the existing recording-export-quality enum through the record command down to the Swift export preset. Adds a `--export-quality ` option for iOS recordings that controls the AVAssetExportSession preset used when a recording is re-encoded. `medium` stays the default and selects AVAssetExportPresetMediumQuality, which preserves the fast simulator-friendly export. `high` opts into AVAssetExportPresetHighestQuality for evidence-grade output. This is separate from the existing integer `--quality <5-10>` capture flag that scales render resolution. Closes #568 --- .../RecordingScripts/recording-resize.swift | 45 ++++++++++- src/client-normalizers.ts | 1 + src/client-types.ts | 3 + src/commands/recording/index.test.ts | 16 ++++ src/commands/recording/index.ts | 9 ++- .../recording-export-quality.test.ts | 33 ++++++++ src/core/recording-export-quality.ts | 23 ++++++ .../handlers/__tests__/record-trace.test.ts | 75 ++++++++++++++++++- src/daemon/handlers/record-trace-recording.ts | 16 ++++ src/daemon/handlers/record-trace-types.ts | 2 + src/daemon/types.ts | 2 + src/recording/__tests__/overlay.test.ts | 29 ++++++- src/recording/overlay.ts | 14 +++- src/utils/__tests__/args.test.ts | 3 +- src/utils/cli-flags.ts | 14 ++++ website/docs/docs/commands.md | 2 + 16 files changed, 275 insertions(+), 12 deletions(-) create mode 100644 src/core/__tests__/recording-export-quality.test.ts create mode 100644 src/core/recording-export-quality.ts diff --git a/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift b/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift index de489539d..a4a748255 100644 --- a/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +++ b/ios-runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift @@ -74,7 +74,8 @@ func run() throws { instruction.layerInstructions = [layerInstruction] videoComposition.instructions = [instruction] - guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else { + let presetName = exportPresetName(for: parsedArgs.exportQuality, compatibleWith: composition) + guard let exporter = AVAssetExportSession(asset: composition, presetName: presetName) else { throw ResizeError.exportFailed("Failed to create export session.") } @@ -97,10 +98,20 @@ func run() throws { } } -func parseArguments(_ arguments: [String]) throws -> (inputPath: String, outputPath: String, quality: Int) { +enum ExportQuality: String { + case medium + case high +} + +func parseArguments( + _ arguments: [String] +) throws -> (inputPath: String, outputPath: String, quality: Int, exportQuality: ExportQuality) { var inputPath: String? var outputPath: String? var quality: Int? + // Export quality defaults to medium so existing callers keep the fast, simulator-friendly + // export. Pass --export-quality high to opt into a slower highest-quality export. + var exportQuality: ExportQuality = .medium var index = 0 while index < arguments.count { @@ -122,6 +133,15 @@ func parseArguments(_ arguments: [String]) throws -> (inputPath: String, outputP } quality = parsed index += 2 + case "--export-quality": + guard nextIndex < arguments.count else { + throw ResizeError.invalidArgs("--export-quality requires a value") + } + guard let parsed = ExportQuality(rawValue: arguments[nextIndex]) else { + throw ResizeError.invalidArgs("--export-quality must be one of: medium, high") + } + exportQuality = parsed + index += 2 default: throw ResizeError.invalidArgs("Unknown argument: \(argument)") } @@ -129,10 +149,27 @@ func parseArguments(_ arguments: [String]) throws -> (inputPath: String, outputP guard let inputPath, let outputPath, let quality else { throw ResizeError.invalidArgs( - "Usage: recording-resize.swift --input