[avas] AVAudioSession.mm:1080:-[AVAudioSession setActive:withOptions:error:]

1,853 阅读1分钟

对接广点通带视频的信息流,导致播放器播放影片的过程中声音被关闭,具体报错如下

[avas] AVAudioSession.mm:1080:-[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.  

由于影片正在播放,而广点通信息流的视频播放完毕后,将setActive设置为NO,导致声音无法输出。

具体解决方法:

  • 创建AVAudioSession的分类XCAudioSession,在分类中重写此方法,拦截这个设置,返回YES和NO都可以,默认情况下AVAudioSession已经开启

链接:www.jianshu.com/p/507a39b83…

-(BOOL)setActive:(BOOL)active withOptions:(AVAudioSessionSetActiveOptions)options error:(NSError*_Nullable__autoreleasing*)outError {
    return YES; 
}
  • 创建AVAudioSession的分类XCAudioSession,hook setActive:withOptions:error:方法,然后判断是否正在播放页面,如果在则active设置成YES,如果没有在,则根据设置即可。此方法可根据自己需求控制active。

链接:www.jianshu.com/p/139907140…

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSEL = @selector(setActive:withOptions:error:);
        SEL swizzledSEL = @selector(xc_setActive:withOptions:error:);

        Method originalMethod = class_getInstanceMethod(class, originalSEL);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSEL);

        BOOL didAddMethod = class_addMethod(class, originalSEL , method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class, swizzledSEL, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (BOOL)xc_setActive:(BOOL)active withOptions:(AVAudioSessionSetActiveOptions)options error:(NSError * _Nullable __autoreleasing *)outError {
    BOOL customActive = [XCPlayerManager shareInstance].isPlayView ? YES : active;
    return [self xc_setActive:customActive withOptions:options error:outError];
}

注:广点通官方有如下设置:

音频设置

广点通SDK默认设置:category为AVAudioSessionCategoryAmbient,options为AVAudioSessionCategoryOptionDuckOthers

在播放音频时是否使用SDK内部对AVAudioSession设置的category及options,默认使用,若不使用,SDK内部不做任何处理,由调用方在播放视频时自行设置;

#import "GDTSDKConfig.h"

+ (void)enableDefaultAudioSessionSetting:(BOOL)enabled;