iOS ijkplayer Audio Unit 播放音频

来源:互联网 发布:qq关系数据库 编辑:程序博客网 时间:2024/06/05 07:43

设置AudioUnit的播放的方法参考上一篇文章 此处不再多说

这里给出AudioUnit的代码请查阅

/* * IJKSDLAudioUnitController.h * * Copyright (c) 2013 Bilibili * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com> * * based on https://github.com/kolyvan/kxmovie * * This file is part of ijkPlayer. * * ijkPlayer is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * ijkPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with ijkPlayer; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#import <Foundation/Foundation.h>#include "ijksdl/ijksdl_aout.h"@interface IJKSDLAudioUnitController : NSObject- (id)initWithAudioSpec:(const SDL_AudioSpec *)aSpec;- (void)play;- (void)pause;- (void)flush;- (void)stop;- (void)close;- (void)setPlaybackRate:(float)playbackRate;- (void)setPlaybackVolume:(float)playbackVolume;- (double)get_latency_seconds;@property (nonatomic, readonly) SDL_AudioSpec spec;@end


/* * IJKSDLAudioUnitController.m * * Copyright (c) 2013 Bilibili * Copyright (c) 2013 Zhang Rui <bbcallen@gmail.com> * * based on https://github.com/kolyvan/kxmovie * * This file is part of ijkPlayer. * * ijkPlayer is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * ijkPlayer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with ijkPlayer; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#import "IJKSDLAudioUnitController.h"#import "IJKSDLAudioKit.h"#include "ijksdl/ijksdl_log.h"#import <AVFoundation/AVFoundation.h>@implementation IJKSDLAudioUnitController {    AudioUnit _auUnit;    BOOL _isPaused;}- (id)initWithAudioSpec:(const SDL_AudioSpec *)aSpec{    self = [super init];    if (self) {        if (aSpec == NULL) {            self = nil;            return nil;        }        _spec = *aSpec;                if (aSpec->format != AUDIO_S16SYS) {            NSLog(@"aout_open_audio: unsupported format %d\n", (int)aSpec->format);            return nil;        }                if (aSpec->channels > 6) {            NSLog(@"aout_open_audio: unsupported channels %d\n", (int)aSpec->channels);            return nil;        }                AudioComponentDescription desc;        IJKSDLGetAudioComponentDescriptionFromSpec(&_spec, &desc);                AudioComponent auComponent = AudioComponentFindNext(NULL, &desc);        if (auComponent == NULL) {            ALOGE("AudioUnit: AudioComponentFindNext failed");            self = nil;            return nil;        }                AudioUnit auUnit;        OSStatus status = AudioComponentInstanceNew(auComponent, &auUnit);        if (status != noErr) {            ALOGE("AudioUnit: AudioComponentInstanceNew failed");            self = nil;            return nil;        }                UInt32 flag = 1;        status = AudioUnitSetProperty(auUnit,                                      kAudioOutputUnitProperty_EnableIO,                                      kAudioUnitScope_Output,                                      0,                                      &flag,                                      sizeof(flag));        if (status != noErr) {            ALOGE("AudioUnit: failed to set IO mode (%d)", (int)status);        }                /* Get the current format */        _spec.format = AUDIO_S16SYS;        _spec.channels = 2;        AudioStreamBasicDescription streamDescription;        IJKSDLGetAudioStreamBasicDescriptionFromSpec(&_spec, &streamDescription);                /* Set the desired format */        UInt32 i_param_size = sizeof(streamDescription);        status = AudioUnitSetProperty(auUnit,                                      kAudioUnitProperty_StreamFormat,                                      kAudioUnitScope_Input,                                      0,                                      &streamDescription,                                      i_param_size);        if (status != noErr) {            ALOGE("AudioUnit: failed to set stream format (%d)", (int)status);            self = nil;            return nil;        }                /* Retrieve actual format */        status = AudioUnitGetProperty(auUnit,                                      kAudioUnitProperty_StreamFormat,                                      kAudioUnitScope_Input,                                      0,                                      &streamDescription,                                      &i_param_size);        if (status != noErr) {            ALOGE("AudioUnit: failed to verify stream format (%d)\n", (int)status);        }                AURenderCallbackStruct callback;        callback.inputProc = (AURenderCallback) RenderCallback;        callback.inputProcRefCon = (__bridge void*) self;        status = AudioUnitSetProperty(auUnit,                                      kAudioUnitProperty_SetRenderCallback,                                      kAudioUnitScope_Input,                                      0, &callback, sizeof(callback));        if (status != noErr) {            ALOGE("AudioUnit: render callback setup failed (%d)\n", (int)status);            self = nil;            return nil;        }                SDL_CalculateAudioSpec(&_spec);                /* AU initiliaze */        status = AudioUnitInitialize(auUnit);        if (status != noErr) {            ALOGE("AudioUnit: AudioUnitInitialize failed (%d)\n", (int)status);            self = nil;            return nil;        }                _auUnit = auUnit;    }    return self;}- (void)dealloc{    [self close];}- (void)play{    if (!_auUnit)        return;        _isPaused = NO;    NSError *error = nil;    if (NO == [[AVAudioSession sharedInstance] setActive:YES error:&error]) {        NSLog(@"AudioUnit: AVAudioSession.setActive(YES) failed: %@\n", error ? [error localizedDescription] : @"nil");    }        OSStatus status = AudioOutputUnitStart(_auUnit);    if (status != noErr)        NSLog(@"AudioUnit: AudioOutputUnitStart failed (%d)\n", (int)status);}- (void)pause{    if (!_auUnit)        return;        _isPaused = YES;    OSStatus status = AudioOutputUnitStop(_auUnit);    if (status != noErr)        ALOGE("AudioUnit: failed to stop AudioUnit (%d)\n", (int)status);}- (void)flush{    if (!_auUnit)        return;        AudioUnitReset(_auUnit, kAudioUnitScope_Global, 0);}- (void)stop{    if (!_auUnit)        return;        OSStatus status = AudioOutputUnitStop(_auUnit);    if (status != noErr)        ALOGE("AudioUnit: failed to stop AudioUnit (%d)", (int)status);}- (void)close{    [self stop];        if (!_auUnit)        return;        AURenderCallbackStruct callback;    memset(&callback, 0, sizeof(AURenderCallbackStruct));    AudioUnitSetProperty(_auUnit,                         kAudioUnitProperty_SetRenderCallback,                         kAudioUnitScope_Input, 0, &callback,                         sizeof(callback));        AudioComponentInstanceDispose(_auUnit);    _auUnit = NULL;}- (void)setPlaybackRate:(float)playbackRate{    //    if (fabsf(playbackRate - 1.0f) <= 0.000001) {    //        UInt32 propValue = 1;    //        AudioQueueSetProperty(_audioQueueRef, kAudioQueueProperty_TimePitchBypass, &propValue, sizeof(propValue));    //        AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_PlayRate, 1.0f);    //    } else {    //        UInt32 propValue = 0;    //        AudioQueueSetProperty(_audioQueueRef, kAudioQueueProperty_TimePitchBypass, &propValue, sizeof(propValue));    //        AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_PlayRate, playbackRate);    //    }}- (void)setPlaybackVolume:(float)playbackVolume{    //    float aq_volume = playbackVolume;    //    if (fabsf(aq_volume - 1.0f) <= 0.000001) {    //        AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_Volume, 1.f);    //    } else {    //        AudioQueueSetParameter(_audioQueueRef, kAudioQueueParam_Volume, aq_volume);    //    }}//- (double)get_latency_seconds//{//    return ((double)(kIJKAudioQueueNumberBuffers)) * _spec.samples / _spec.freq;//}- (double)get_latency_seconds{    return (double) _spec.samples / _spec.freq;}static OSStatus RenderCallback(void                        *inRefCon,                               AudioUnitRenderActionFlags  *ioActionFlags,                               const AudioTimeStamp        *inTimeStamp,                               UInt32                      inBusNumber,                               UInt32                      inNumberFrames,                               AudioBufferList             *ioData){    @autoreleasepool {        IJKSDLAudioUnitController* auController = (__bridge IJKSDLAudioUnitController *) inRefCon;                if (!auController || auController->_isPaused) {            for (UInt32 i = 0; i < ioData->mNumberBuffers; i++) {                AudioBuffer *ioBuffer = &ioData->mBuffers[i];                memset(ioBuffer->mData, auController.spec.silence, ioBuffer->mDataByteSize);            }            return noErr;        }                for (int i = 0; i < (int)ioData->mNumberBuffers; i++) {            AudioBuffer *ioBuffer = &ioData->mBuffers[i];            (*auController.spec.callback)(auController.spec.userdata, ioBuffer->mData, ioBuffer->mDataByteSize);        }                return noErr;    }}@end



原创粉丝点击