Почему я не могу воспроизводить звуковые файлы, записанные AVAudioRecorder?

Вот как я определил myrecorder и myplayer

var myrecorder:AVAudioRecorder!
var myplayer : AVAudioPlayer!

Это код для настройки myrecorder в viewDidLoad().

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    filepath = "\(getDocumentsDirectory())/001.caf"
    print(filepath)

    try! session.setCategory(AVAudioSessionCategoryPlayAndRecord)
    //define settings
    let recordSettings: [String: AnyObject] = [
        AVFormatIDKey: NSNumber(unsignedInt: kAudioFormatMPEG4AAC),
        AVEncoderAudioQualityKey : AVAudioQuality.Medium.rawValue,
        AVSampleRateKey: 44100.0,
        AVNumberOfChannelsKey: 2,
    ]
    myrecorder = try! AVAudioRecorder(URL: NSURL(fileURLWithPath: filepath), settings: recordSettings)
    myrecorder.delegate = self
    myrecorder.prepareToRecord()
}

И у меня есть кнопки для управления записью и остановкой, и я получил файл 001.caf. Я могу воспроизвести звуковой файл, но я думаю, что файл недостаточно хорош.

@IBAction func Play() {
    try! myplayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: filepath))
    myplayer.volume = 0.5
    myplayer.play()
    print("Playing...")
}

Воспроизведение проходит успешно без каких-либо ошибок или сбоев. Есть только одна проблема, нет звука при воспроизведении.

Я предполагаю, что я что-то пропустил на этапе записи, но я не мог найти это. Пожалуйста помоги.


person shawhu    schedule 27.11.2015    source источник


Ответы (2)


Проблема связана с AVAudioPlayer, созданным в этой строке.

try! myplayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: filepath))

Этот экземпляр myplayer будет освобожден, как только завершится функция воспроизведения.

Создайте экземпляр проигрывателя AVAudio в другой функции, такой как Viewdidload, чтобы он оставался даже после того, как элемент управления покидает функцию воспроизведения.

person TheAppMentor    schedule 27.11.2015
comment
Нет, это не работает. У меня есть myplayer, определяющий снаружи. Позвольте мне исправить вопрос правильно - person shawhu; 28.11.2015
comment
И, кстати, это не делает экземпляр постоянным, если вы инициируете его в Viewdidload. Чтобы прикрепить экземпляр, вам нужно будет определить его вне какого-либо конкретного метода, что эффективно заставит его привязываться к себе. Когда есть «я», есть и объект. А также вы не можете поставить слабый, когда определяете его. Где и когда инициализировать экземпляр не имеет значения. Я думал, что мне не нужно показывать код определения, потому что у меня не было LET перед именем моего экземпляра, что означает, что я определил его снаружи. Все дело в ОБЪЕМЕ переменной. - person shawhu; 28.11.2015

Хорошо, наконец я нашел проблему.

ВЫ НЕ МОЖЕТЕ ИСПОЛЬЗОВАТЬ AVAudioSessionCategoryPlayAndRecord.

При записи приходилось использовать AVAudioSessionCategoryRecord, а при воспроизведении — AVAudioSessionCategoryPlayback. И вы устанавливаете сеанс вперед и назад при воспроизведении и записи.

AVAudioSessionCategoryPlayAndRecord используется, когда воспроизведение и запись необходимы одновременно, например, при голосовом чате...

person shawhu    schedule 28.11.2015
comment
Не так. В документации к AVAudioSessionCategoryPlayAndRecord говорится: Эта категория подходит для одновременной записи и воспроизведения, а также для приложений, которые записывают и воспроизводят, но не одновременно [курсив мой]. - person matt; 28.11.2015
comment
Попробуйте сами. Думаю, мы не можем на 100% следовать тому, что говорится в документе. В моем случае, если бы я использовал AVAudioSessionCategoryPlayAndRecord, я не смог бы воспроизвести записанный файл CAF. Когда я переключаю тип на Воспроизведение при воспроизведении и Запись при записи, все работает. - person shawhu; 28.11.2015
comment
Я заметил в вашем коде, что вы устанавливаете категорию сеанса, но никогда не активируете сеанс. Скорее всего проблема в этом. - person matt; 28.11.2015