Я просто хочу получить список маркеров в аудио файле. Я думал, что это будет простая общая задача, которая не будет слишком сложной. Тем не менее, я едва могу найти какой-либо пример кода или документации, поэтому я закончил с этим:
private func getMarkers(_ url: CFURL) -> AudioFileMarkerList {
var file: AudioFileID?
var size: UInt32 = 0
var markers = AudioFileMarkerList()
AudioFileOpenURL(url, .readPermission, kAudioFileWAVEType, &file)
AudioFileGetPropertyInfo(file!, kAudioFilePropertyMarkerList, &size, nil)
AudioFileGetProperty(file!, kAudioFilePropertyMarkerList, &size, &markers)
return markers
}
К сожалению, это не работает: error: memory read failed for 0x0
.
Я просто не могу понять проблему. Я проверил URL и размер (оба они действительны), но всегда не удается получить маркеры. Любая помощь с этим была бы фантастической!
EDIT: Такие работы, но все данные полностью неправильны, и я не могу понять, как один аудиофайл может иметь несколько AudioFileMarkerLists маркеров:
private func getMarkers(_ url: CFURL) -> [AudioFileMarkerList] {
var file: AudioFileID?
var size: UInt32 = 0
AudioFileOpenURL(url, .readPermission, kAudioFileWAVEType, &file)
AudioFileGetPropertyInfo(file!, kAudioFilePropertyMarkerList, &size, nil)
let length = NumBytesToNumAudioFileMarkers(Int(size))
var markers = [AudioFileMarkerList](repeating: AudioFileMarkerList(), count: length)
AudioFileGetProperty(file!, kAudioFilePropertyMarkerList, &size, &markers)
return markers
}
EDIT 2: В соответствии с большинством ответов, которые я видел до сих пор, это должно работать, но оно возвращает пустой массив:
private func getMarkers(_ url: CFURL) -> [AudioFileMarkerList] {
var file: AudioFileID?
var size: UInt32 = 0
AudioFileOpenURL(url, .readPermission, kAudioFileWAVEType, &file)
AudioFileGetPropertyInfo(file!, kAudioFilePropertyMarkerList, &size, nil)
let length = NumBytesToNumAudioFileMarkers(Int(size))
var markers = [AudioFileMarkerList]()
markers.reserveCapacity(length)
AudioFileGetProperty(file!, kAudioFilePropertyMarkerList, &size, &markers)
return markers
}
ИЗМЕНИТЬ 3: Я избавился от кучи ошибок и полезных вещей из кода Райана для тех, кто хочет быстро попробовать и найти проблему:
private func getMarkers(_ url: CFURL) -> [AudioFileMarker]? {
var file: AudioFileID?
var size: UInt32 = 0
var markers: [AudioFileMarker] = []
AudioFileOpenURL(url, .readPermission, kAudioFileWAVEType, &file)
AudioFileGetPropertyInfo(file!, kAudioFilePropertyMarkerList, &size, nil)
let length = NumBytesToNumAudioFileMarkers(Int(size))
let data = UnsafeMutablePointer<AudioFileMarkerList>.allocate(capacity: length)
AudioFileGetProperty(file!, kAudioFilePropertyMarkerList, &size, data)
markers.append(data.pointee.mMarkers)
data.deallocate(capacity: length)
return markers
}
Я просто надеюсь, что Apple действительно проверила AudioFileMarkerList в первую очередь.
РЕДАКТИРОВАТЬ 4: РЕШЕНИЕ благодаря ритмическому Фистману и Райану Франческони! Конечный результат:
private func getMarkers(_ url: CFURL) -> [AudioFileMarker]? {
var file: AudioFileID?
var size: UInt32 = 0
var markerList: [AudioFileMarker] = []
AudioFileOpenURL(url, .readPermission, kAudioFileWAVEType, &file)
AudioFileGetPropertyInfo(file!, kAudioFilePropertyMarkerList, &size, nil)
let length = NumBytesToNumAudioFileMarkers(Int(size))
let data = UnsafeMutablePointer<AudioFileMarkerList>.allocate(capacity: length)
AudioFileGetProperty(file!, kAudioFilePropertyMarkerList, &size, data)
let markers = UnsafeBufferPointer<AudioFileMarker>(start: &data.pointee.mMarkers, count: length)
for marker in markers {
markerList.append(marker)
}
data.deallocate(capacity: length)
return markerList
}