10

我创建了自己的自定义控件,用于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。我在 SO 上看到了其他帖子,说只是创建一个实例AVAudioPlayer并设置音量,但这只会导致我的应用程序崩溃,我希望这与我没有使用initWithContentsOfURL:error:orinitWithData:error:而是使用 `的事实有关在里面'。

任何帮助,将不胜感激。

4

2 回答 2

10

与 Apple 技术人员交谈后,发现无法使用MPMoviePlayerController.

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

一旦你使用它,它就是创建自定义音频混合和设置音量级别的问题。它实际上工作得很好。

示例代码:

    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 并在这篇文章中添加链接。

于 2013-04-19T11:15:01.820 回答
4

我知道这是一篇旧帖子,但我设法找到了一种方法,使用 MPVolumeView 成功控制 iOS6 和 iOS7 中 MPMoviePlayerController 控件的音量。一个问题是它不能在模拟器中工作,只能在物理设备上工作。为了控制音量,添加一个隐藏的 MPVolumeView 就可以了。但是,如果您使用隐藏的,当您使用物理设备音量按钮更改音量时出现的本机操作系统音量显示仍将出现在中央屏幕上。如果您想防止这种情况发生,请确保您的 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 应用程序现在已使用此方法获得批准,并且已在应用程序商店上架。

于 2014-08-05T17:58:18.263 回答