Audio Ducking之后音乐更柔和了?

时间:2015-04-15 19:25:14

标签: ios swift audio avaudiosession

我有一些代码用于在我的应用程序中实现音频闪避。当用户正在收听某些音乐,然后进入某个位置时,将播放特定的音乐片段。当发生这种情况时,正在播放的原始音乐" ducks" (或者变得更加沉默)和我的应用程序开始播放的新音乐片段。然而,在音乐结束播放之后,正在播放的原始音乐再次播放,但比以前更加柔和。有想法该怎么解决这个吗?以下是我的代码:

audioPlayer = AVAudioPlayer(data: NSData(contentsOfMappedFile: musicFilePath), error: nil)

//Before music is played, make sure background music is off and audio ducking is turned on
AVAudioSession.sharedInstance().setActive(false, withOptions: AVAudioSessionSetActiveOptions.allZeros, error: nil)
        AVAudioSession.sharedInstance().setCategory("AVAudioSessionCategoryPlayback", withOptions: AVAudioSessionCategoryOptions.DuckOthers, error: nil)

audioPlayer.prepareToPlay()
audioPlayer.play()

//Allows audio player to play in the background & turn back on previously played music.
AVAudioSession.sharedInstance().setCategory("AVAudioSessionCategoryAmbient", withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil) 

我试图查看文档,但没有找到太多。任何帮助,将不胜感激。谢谢!

编辑:基于以下答案的音频闪避时代码如何:

       audioPlayer = AVAudioPlayer(data: NSData(contentsOfMappedFile: musicFilePath), error: nil)

        AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
        AVAudioSession.sharedInstance().setActive(true, error: nil)

        audioPlayer.prepareToPlay()
        audioPlayer.play()

        AVAudioSession.sharedInstance().setActive(false, error: nil)
        AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
        AVAudioSession.sharedInstance().setActive(true, error: nil)

编辑2:

audioPlayer = AVAudioPlayer(data: NSData(contentsOfMappedFile: musicFilePath), error: nil)
audioPlayer.delegate = self
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)

audioPlayer.prepareToPlay()
audioPlayer.play()

然后在audioPlayerDidFinishPlaying方法中,我放置了代码来放弃音频:

func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool){
    //Prepare to play after Sound finished playing
    AVAudioSession.sharedInstance().setActive(false, error: nil)
    AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
    AVAudioSession.sharedInstance().setActive(true, error: nil)
}

3 个答案:

答案 0 :(得分:1)

设置audiosession激活:读取时为YES,完成读取后,在didfinish delegate设置为NO

-(void)createAVSpeech : (NSString*) readString{


    audioSession_ = [AVAudioSession sharedInstance];

    NSError *setCategoryError = nil;

    [audioSession_ setCategory:AVAudioSessionCategoryPlayback
                   withOptions:AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];

    NSError *activationError = nil;
    [audioSession_ setActive:YES error:&activationError];

    speech_ = [[AVSpeechSynthesizer alloc] init];
    speech_.delegate = self;

    AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:readString];
    NSString *readLang = @"en-US";
    float speedrate = 1;
    utterance.rate = AVSpeechUtteranceDefaultSpeechRate * speedrate;
    utterance.pitchMultiplier =0.8;

    utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:readLang];

    [speech_ speakUtterance:utterance];
}


-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{

    NSLog(@"did finish speech");
        [audioSession_ setActive:NO error:nil];
}

答案 1 :(得分:0)

你没有激活你的躲避会话,所以我不确定它为什么会工作。你可以这样做吗?

AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)

要解开它应该足以使会话失效:

AVAudioSession.sharedInstance().setActive(false, error: nil)

否则尝试停用会话并在关闭闪避后重新激活会话?

AVAudioSession.sharedInstance().setActive(false, error: nil)
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, withOptions: AVAudioSessionCategoryOptions.allZeros, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)

P.S。使用类别符号而不是原始字符串!

答案 2 :(得分:0)

我遇到了同样的问题,这篇文章真的对我很有帮助,但是我不得不用代码来调整它以使它工作。我觉得我应该发布我的代码来帮助别人......

let tts = TextToSpeechService()
tts.saySomething("Hello StackOverflow")

我这个代码我使用AVSpeechSynthesizer,但它等于使用AVAudioPlayer。 我开始使用

来避开和解开音频
var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];
$('#swiperNext').click(function(e)
   {
       var currentMonth = $('.swiper-slide-active h3').html();
       var month = monthNames.indexOf(currentMonth);
       var d = new Date();
       var start = new Date(d.getFullYear(),month,1);
       var end = new Date(d.getFullYear(),month+1,0);
       var startdate = start.getDate()+"/"+(start.getMonth()+1)+"/"+start.getFullYear();
       var enddate = end.getDate()+"/"+(end.getMonth()+1)+"/"+end.getFullYear();
    console.log(startdate+"-"+enddate);
   });

与之前的答案和OP代码的不同之处在于,audioSession仅在应用实际播放声音时激活,并在完成播放声音时立即停用。其他示例包含各种额外的代码(当您的应用确实也播放环境声音时可能会有用,但我在OP的问题中没有看到任何引用。)

(在iOS 9.3.2上使用Swift 2.2在XCode 7.3.1中测试的代码)