使用MPMoviePlayerController播放视频时如何静音/取消静音?

时间:2013-04-11 12:21:59

标签: ios ios6 mpmovieplayercontroller avaudiosession mute

我已创建自己的自定义控件,以便与MPMoviePlayerController一起使用。到目前为止,一切都有效,除了静音按钮控件。

在创建AVAudioSession的实例之前,我使用以下代码配置了MPMoviePlayerController

    NSError *modeError = nil;
    [self.audioSession setMode:AVAudioSessionModeMoviePlayback error:&modeError];
    if (modeError != nil) {
        NSLog(@"Error setting mode for AVAudioSession: %@", modeError);
    }

    NSError *categoryError = nil;
    [self.audioSession setCategory:AVAudioSessionCategoryPlayback error:&categoryError];
    if (categoryError != nil) {
        NSLog(@"Error setting category for AVAudioSession: %@", categoryError);
    }

然后在我的静音按钮回调方法中,我有以下代码:

    NSError *activeError = nil;
    [self.audioSession setActive:NO error:&activeError];
    if (activeError != nil) {
        NSLog(@"Error setting inactive state for AVAudioSession: %@", activeError);
    }

单击“静音”按钮时,出现以下无用错误:

Error Domain=NSOSStatusErrorDomain Code=560030580 "The operation couldn’t be completed. (OSStatus error 560030580.)"

我正在链接到AVFoundation框架。

这真的开始让我感到烦恼,因为我无法为我的生活找到一种方法来减少或静音我的应用程序的播放音​​频。

我不想仅根据AVAudioSession AVAudioSessionCategoryPlayback类别定义的应用程序级别卷更改系统全局卷。

您似乎可以设置AVAudioPlayer的音量而不是MPMoviePlayerController的音量。我在这里看过其他帖子,说只是创建一个AVAudioPlayer的实例并设置音量,但这只会导致我的应用程序崩溃,我希望它与我不使用的事实有关initWithContentsOfURL:error:initWithData:error:而是使用`init'。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:10)

与Apple技术人员交谈后发现,使用MPMoviePlayerController无法控制或静音音频。

相反,您必须使用AVFoundations AVPlayer类创建自己的控制器。

一旦您使用它,就需要创建自定义音频混合并设置音量。它确实很有效。

示例代码:

    AVURLAsset * asset = [AVURLAsset URLAssetWithURL:[self localMovieURL] options:nil];
    NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];

    // Mute all the audio tracks
    NSMutableArray * allAudioParams = [NSMutableArray array];
    for (AVAssetTrack *track in audioTracks) {
            AVMutableAudioMixInputParameters *audioInputParams =[AVMutableAudioMixInputParameters audioMixInputParameters];
            [audioInputParams setVolume:0.0 atTime:kCMTimeZero ];
            [audioInputParams setTrackID:[track trackID]];
            [allAudioParams addObject:audioInputParams];
    }
    AVMutableAudioMix * audioZeroMix = [AVMutableAudioMix audioMix];
    [audioZeroMix setInputParameters:allAudioParams];

    // Create a player item
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
    [playerItem setAudioMix:audioZeroMix]; // Mute the player item

    // Create a new Player, and set the player to use the player item
    // with the muted audio mix
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

    self.mPlayer = player;

    [mPlayer play];

我写了一个MPMoviePlayerController替换类,增加了对音量级别的支持。我将很快上传到github,并在这篇文章中添加链接。

答案 1 :(得分:4)

我知道这是一个老帖子,但我设法找到一种方法来成功控制iOS6中的MPMoviePlayerController控件的音量。 iOS7,使用MPVolumeView。一个问题是它不能在模拟器中工作,只能在物理设备上工作。对于仅控制音量,添加隐藏的MPVolumeView将正常工作。但是,如果使用隐藏的,则使用物理设备音量按钮更改音量时显示的本机OS音量显示仍将显示为中央屏幕。如果要防止这种情况,请确保未隐藏MPVolumeView。相反,您可以为其提供非常低的Alpha透明度并将其放在其他视图后面,这样用户就无法看到它。

以下是我使用过的代码:

MPVolumeView *volumeView = [[MPVolumeView alloc]initWithFrame:CGRectZero];
[volumeView setShowsVolumeSlider:YES];
[volumeView setShowsRouteButton:NO];

// control must be VISIBLE if you want to prevent default OS volume display
// from appearing when you change the volume level
[volumeView setHidden:NO];
volumeView.alpha = 0.1f;
volumeView.userInteractionEnabled = NO;

// to hide from view just insert behind all other views
[self.view insertSubview:volumeView atIndex:0];

这允许您通过调用以下方式来控制音量:     [[MPMusicPlayerController applicationMusicPlayer] setVolume:0.0];

但是当我第一次尝试更改音量时,我仍然看到本机操作系统音量显示出现 - 在后续加载时它没有显示此显示,因此想法它与视图控制器生命周期中的舞台有关,我将它从我的viewDidLoad方法移动到viewDidAppear方法 - 它工作 - 音量静音,原始音量显示没有出现,我现在能够在视频之前听到一瞬间的音频开始玩了。所以我迷上了回放状态确实改变了MPMoviePlayerController的委托。在viewDidload中我添加了:

[[NSNotificationCenter defaultCenter] addObserver:self 
    selector:@selector(videoPlaybackStateDidChange:) 
    name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];

委托回调方法:

-(void)videoPlaybackStateDidChange:(NSNotification *)aNotification
{
    // Note, this doesn't work in simulator (even in iOS7), only on actual device!
    if ([moviePlayerController playbackState] == MPMoviePlaybackStatePlaying)
    {
        [[MPMusicPlayerController applicationMusicPlayer] setVolume:0.0];
    }
}

在开始播放之前,视频的音频静音,但在生命周期中的viewDidLoad之后,所以没有原生操作系统音量静音显示。

在我的应用程序中,我在静音之前检索并存储当前音量级别(使用[MPMusicPlayerController applicationMusicPlayer] .volume属性),然后在视图控制器关闭时将音量恢复到此级别,这意味着用户将不会意识到他们的设备音量已被修改并恢复。

另外,如果您的MPMoviePlayerController在iOS7中使用非标准音频路由,则调用[[MPMusicPlayerController applicationMusicPlayer] setVolume:0.0]可能对您不起作用 - 在这种情况下,您可以遍历MPVolumeView控件的子视图,直到您找到一个子类UISlider的视图。然后你可以调用[sliderView setValue:0 animated:NO],它应该适合你。这种方法不使用任何私有Apple API,因此不应该拒绝您的应用程序 - 毕竟有很多正当理由可以提供此功能,并且在iOS6中可以不必去这些长度!事实上,我发现Apple已经删除了在iOS7中首先在MPMoviePlayerController上设置音量的功能..强制迁移到AVPlayer?

更新:我的iPad应用程序现已通过此方法获得批准,并且已在应用商店中发布。