Closed said13 closed 8 months ago
Does the app have write access to the file system? In my testing that is a common problem. Is there a line similar to fopen failed: Read-only file system (30)
in the log?
Are there any other log messages displayed during encoding? What type of audio does inputURL
contain?
The Ogg Opus encoder is a standalone encoder so the .coreAudio
encoder settings don't apply. The Opus-specific settings are here.
Thank you for your fast answer! Writing is enabled, there is no problem with it.
This is the settings which I use for recording via AVAudiorecorder and it writes a file .wav
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey: 32,
AVLinearPCMIsBigEndianKey: false,
AVLinearPCMIsFloatKey: true
]
and this is the settings for converted(updated after your answer)
encoder.settings = [
AudioEncodingSettingsKey.opusPreserveSampleRate: 48000,
AudioEncodingSettingsKey.opusComplexity: 10,
AudioEncodingSettingsKey.opusSignalType: OpusSignalType.voice,
AudioEncodingSettingsKey.opusFrameDuration: OpusFrameDuration.duration100ms,
AudioEncodingSettingsKey.opusBitrate: 256,
AudioEncodingSettingsKey.opusBitrateMode: OpusBitrateMode.VBR,
]
As a result I see a file with same content:
OggS���������ўђЈ
����]OpusHead8Dђ�����OggS����������ўђЈ
���@«ЦД€€юOpusTags���libopus 1.4, opus 1.4���5���ENCODER=SFBAudioEngine Ogg Opus Encoder (libopus 1.4)����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������OggS�8������ўђЈ`���Фmdрш€ю
I am doing something wrong or do I need any other code to convert it successfully?
Could you share a short audio file that you're using for input? I created a mono 32-bit float WAV and was able to convert it with no issues.
What is the output of afinfo
for the input file?
For me the following file
% afinfo ~/Desktop/untitled\ \#1.wav
File: /Users/x/Desktop/untitled #1.wav
File type ID: WAVE
Num Tracks: 1
----
Data format: 1 ch, 44100 Hz, Float32
no channel layout.
estimated duration: 0.180000 sec
audio bytes: 31752
audio packets: 7938
bit rate: 1411200 bits per second
packet size upper bound: 4
maximum packet size: 4
audio data file offset: 44
optimized
source bit depth: F32
----
using the following settings
encoder.settings = [
.opusPreserveSampleRate: true,
.opusComplexity: 10,
.opusSignalType: OpusSignalType.voice,
.opusFrameDuration: OpusFrameDuration.duration100ms,
.opusBitrate: 256,
.opusBitrateMode: OpusBitrateMode.VBR,
]
converts correctly.
(Note that .opusPreserveSampleRate
is meant to be a boolean value but any nonzero value is handled as true).
VoiceRecord_20240201210910_F3B08F9C-012B-4DC9-AE07-2300C1125BE1.wav.zip
Here is the file. Also the output of afinfo:
File type ID: WAVE Num Tracks: 1 Data format: 1 ch, 44100 Hz, Float32 no channel layout. estimated duration: 3.658322 sec audio bytes: 645328 audio packets: 161332 bit rate: 1411200 bits per second packet size upper bound: 4 maximum packet size: 4 audio data file offset: 4096 optimized source bit depth: F32
My code looks like this now:
let outputSource = try OutputSource(for: outputURL)
let encoder = try AudioEncoder(outputSource: outputSource, encoderName: .oggOpus)
encoder.settings = [
.opusPreserveSampleRate: true,
.opusComplexity: 10,
.opusSignalType: OpusSignalType.voice,
.opusFrameDuration: OpusFrameDuration.duration100ms,
.opusBitrate: 256,
.opusBitrateMode: OpusBitrateMode.VBR,
]
try AudioConverter.convert(inputURL, using: encoder)
Do I need to call any other functions to complete conversion?
Does that produce a working opus file?
Unfortunately not.
If you step through the conversion in the debugger where is it failing?
That file converts correctly using a slightly modified SimplePlayer-macOS:
--- a/SimplePlayer-macOS/AppDelegate.swift
+++ b/SimplePlayer-macOS/AppDelegate.swift
@@ -86,7 +86,7 @@ class AppDelegate: NSObject {
openPanel.allowedFileTypes = PlayerWindowController.supportedPathExtensions
if openPanel.runModal() == .OK, let url = openPanel.url {
- let destURL = url.deletingPathExtension().appendingPathExtension("wav")
+ let destURL = url.deletingPathExtension().appendingPathExtension("opus")
if FileManager.default.fileExists(atPath: destURL.path) {
let alert = NSAlert()
alert.messageText = "Do you want to overwrite the existing file?"
@@ -100,7 +100,16 @@ class AppDelegate: NSObject {
}
do {
- try AudioConverter.convert(url, to: destURL)
+ let encoder = try AudioEncoder(url: destURL, encoderName: .oggOpus)
+ encoder.settings = [
+ .opusPreserveSampleRate: true,
+ .opusComplexity: 10,
+ .opusSignalType: OpusSignalType.voice,
+ .opusFrameDuration: OpusFrameDuration.duration100ms,
+ .opusBitrate: 256,
+ .opusBitrateMode: OpusBitrateMode.VBR,
+ ]
+ try AudioConverter.convert(url, using: encoder)
// Silently fail if metadata can't be copied
try? AudioFile.copyMetadata(from: url, to: destURL)
} catch let error {
Thank you @sbooth, it works as expected now!
Hi there. Thank you for your great library! I am having issues while converting .wav to .oggOpus. Conversion completes without errors, but the audio file has 0 duration. Here is my code:
Output url is an empty file with an extension "opus" which I create before converting.
UPD: Even without creating a file before the converting nothing changes.