8

MPAudioPlayerController を使用して iPod 音楽ライブラリにアクセスし、AVAudioPlayer を使用して音楽の上にオーディオをオーバーレイするアプリを作成しました。このドキュメントをガイドとして使用しました。具体的には:

最後に、カテゴリを拡張して、オーディオの再生中に他のオーディオの音量を自動的に下げることができます。これは、たとえば、運動アプリケーションで使用できます。アプリケーションが音声メッセージをオーバーレイしたいときに、ユーザーが iPod に向かって運動しているとします。たとえば、「あなたは 10 分間ボートを漕いでいます。アプリケーションからのメッセージが理解できるようにするには、kAudioSessionProperty_OtherMixableAudioShouldDuck プロパティをオーディオ セッションに適用します。ダッキングが行われると、電話の音声を除く、デバイス上の他のすべての音声の音量が下がります。

しかし、私はこの動作を見ていません。実際、私が見た (むしろ聞いた) ことは、kAudioSessionProperty_OtherMixableAudioShouldDuck を true に設定して AudioSession をセットアップすると、MPAudioPlayerController の初期ボリュームが減少し、MPAudioPlayerController で一時停止を呼び出す (そして再度再生する) と、ボリューム レベルが低下することです。 「通常」レベルまで上昇します。AVAudioPlayer を再生しても、オーディオ レベルには影響しません...

そこで、これを再現するための簡単なテスト ケースを設定しました。

ViewController ヘッダーで:

#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

@interface MusicPlayerVolumeTestViewController : UIViewController <AVAudioPlayerDelegate>
{
    UIButton *musicButton;
    UIButton *soundButton;
    AVAudioPlayer *audioPlayer;
    MPMusicPlayerController *musicPlayerController;
}
@property (nonatomic, retain) IBOutlet UIButton *musicButton;
@property (nonatomic, retain) IBOutlet UIButton *soundButton;
@property (nonatomic, retain) MPMusicPlayerController *musicPlayerController;

- (IBAction)musicAction;
- (IBAction)soundAction;

@end

そして実装では:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Setup our Audio Session
    OSStatus status = AudioSessionInitialize(NULL, NULL, NULL, NULL);    
    //We want our audio to play if the screen is locked or the mute switch is on
    UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
    status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
    //We want our audio to mix with other app's audio
    UInt32 shouldMix = true;
    status = AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (shouldMix), &shouldMix);
    //Enable "ducking" of the iPod volume level while our sounds are playing
    UInt32 shouldDuck = true;
    AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(shouldDuck), &shouldDuck);
    //Activate our audio session
    AudioSessionSetActive(YES);

    //Setup the Music Player to access the iPod music library
    self.musicPlayerController = [MPMusicPlayerController applicationMusicPlayer];
    [self.musicPlayerController setShuffleMode: MPMusicShuffleModeSongs];
    [self.musicPlayerController setRepeatMode: MPMusicRepeatModeNone];
    [self.musicPlayerController setQueueWithQuery:[MPMediaQuery songsQuery]];

    //Setup a AVAudioPlayer sound to overlay against the Music Player audio
    NSURL *soundURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"mp3"]];
    NSError *error = nil;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error: &error];
    if (!audioPlayer)
    {
        NSLog(@"Could not create audio effect player: %@", [error localizedDescription]);
    }
    [audioPlayer prepareToPlay];
}

- (IBAction)musicAction
{
    if (self.musicPlayerController.playbackState == MPMusicPlaybackStatePlaying)
    {
        [self.musicPlayerController pause];
    }
    else if (self.musicPlayerController.playbackState == MPMusicPlaybackStateStopped
          || self.musicPlayerController.playbackState == MPMusicPlaybackStatePaused)
    {
        [self.musicPlayerController play];
    }
}

- (IBAction)soundAction
{
    if (audioPlayer.playing)
    {
        [audioPlayer pause];
    }
    else
    {
        [audioPlayer play];
    }
}

いくつかの UIButton を配線しました。1 つは musicAction (MPMusicPlayerController の再生/一時停止に使用) 用で、もう 1 つは soundAction (AVAudioPlayer の再生/一時停止に使用) 用です。

前述のように、musicAction ボタンをタップすると音楽が再生されますが、音量レベルが下がり、soundAction ボタンをタップするとオーバーレイが再生されますが、MPMusicPlayerController の音量には影響しません。さらにバグのように、MPMusicPlayerController を一時停止してから再生すると、AudioSession をセットアップしなかった場合と同じレベルまで音楽の音量が上がります。

他の誰かがこの経験をしたことがあるかどうか、もしそうなら、回避策を見つけた場合 (または、私が何か間違ったことをしていることを教えてください) を知りたいです。それ以外の場合は、レーダーに行くと思います。

どうもありがとう、

レヴィ

4

3 に答える 3

9

同様の問題があり、一貫して機能させるのに苦労したときに、この投稿を使用しました。しばらくは機能しますが、「ダッキング」されてしまいます。私はこれを調査してデバッグするのに多くの時間を費やし、最終的にAppleに電話しました。パンくずリストのサンプルコードを見るように言われました。私はその例に従いましたが、すべてうまくいきました。

Apple のサンプル コードは次のとおりです。

http://developer.apple.com/library/ios/#samplecode/Breadcrumb/Introduction/Intro.html

Apple のサポート/開発者は、セッション プロパティを設定する方法とタイミングの順序にも注意するように言いました。どうやらそれがトリックだったようです。ここや他の場所で多くの投稿を読んだ後、互いに競合する設定がありました。ゼロから始めてパンくずの例に従うと、うまくいきました。それ以来、私は問題を抱えていません。

私はここに同じ答えを投稿しました:

AVAudioSession をアンダックする方法

私にとって、この答えは企業秘密の境界線にありました。なぜなら、機能するのは非常に困難であり、市場には機能するアプリがあったからです。私にとっては、音のダッキングとダッキングの解除だけであった実際の例を見ることは、金の重さに値するものでした。

また、これは既知の問題であり、同意しなかったことを Apple に伝えました。彼らはここで問題を認識していませんでした。案の定、ブレッドクラムの例に従えば、奇妙なセッションの非アクティブ化やリアクティブなどなしで機能します。

于 2011-10-01T02:06:18.617 に答える
3

ダッキングは、演奏中のサウンドに自動的に関連付けられるわけではありません。ダッキングをオンにすると、バックグラウンド サウンドがダッキングします。ダッキングをオフにしてオーディオ セッションを無効にすると、バックグラウンド サウンドが元のレベルに戻ります。

でダッキングをオンにしないviewDidLoadでください。実際に音を鳴らしてみるまではオンにしないでください。これにより、バックグラウンド サウンドがダッキングされます。サウンドの再生が終了したら、ダッキングをオフに戻し、オーディオ セッションを非アクティブにして再びアクティブにします。これにより、バックグラウンド サウンドがダッキングされなくなります。

UInt32 duck = 0;
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, 
                        sizeof(duck), &duck);
AudioSessionSetActive(false);
AudioSessionSetActive(true);
于 2011-01-09T03:20:56.303 に答える
2

ドキュメントでは、ダッキングの予想される動作がどのようになるかについては明確ではありませんが、ダッキング用にオーディオセッションを設定した場合、オーディオセッションをアクティブ化するとダッキングし、非アクティブ化するとダッキングすることがわかりました。それ、それはアンダックします。したがって、サウンドキューのためだけに音楽をダックするには、オーディオセッションをアクティブ化および非アクティブ化する必要があります。

私が見つけたバグの1つは、のaudioPlayerDidFinishPlaying:successfully:メソッド内でオーディオセッションを非アクティブ化するAVAudioPlayerDelegateと、ダッキングが削除されず、音量が同じレベルに保たれることです。私はすでにこれについてレーダーを提出しましたが、他の人が同様のものを提出しても害はありません。実際、それはおそらくそれを修正するために彼らにいくらかの圧力をかけるでしょう。

あなたがしているのは、オーディオセッションを開始してそれをオンに保つことです。そのため、サウンドを再生するときに音楽がそれ以上ダックされないように、すぐにアヒルになり、ダックされたままになります。音楽を一時停止して再生した後に音量が戻るという問題は、バグのように聞こえます。

于 2010-07-28T06:26:53.963 に答える