web-dev-qa-db-ja.com

アプリがバックグラウンドで動作しているときにAVPlayerを再生するにはどうすればよいですか?

私は宿題を終えました...ここを読んでいて、ドキュメント、グーグル、スタックオーバーフロー...ですが、ユーザーがアプリをバックグラウンドに移動させても、サウンドを固執させることはできません。

これまでに行ったこと:UIBackgroundModes、オーディオをplistファイルに追加しました。

まずこのコード:

radioAudio = [[AVAudioSession alloc] init];
[radioAudio setCategory:AVAudioSessionCategoryPlayback error:nil];
[radioAudio setActive:YES error:nil];

次にこれ:

NSString *radioURL = @"http://xxx.xxx.xxx/radio.m3u";
radioPlayer = [[AVPlayer playerWithURL:[NSURL URLWithString:radioURL]] retain];

しかし、ユーザーがホームボタンを押すとすぐに、私の音は消えます。

私もこれを見つけましたが、まだ追加されていません。私が読んだいくつかの記事では、それは必要ないと言っています。

newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
     if (newTaskId != UIBackgroundTaskInvalid && bgTaskId != UIBackgroundTaskInvalid)
        [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
bgTaskId = newTaskId;

現時点では、ユーザーが電話で他のことをしているときに、AVPlayerがラジオを歌わせるためにどこに行けばよいのかわかりません。 4.2を搭載したiPhone 4でこれをテストしています。 4.0用にビルドします。

誰でも私が何をすべきか提案がありますか?

30
swe_mattias

同じ問題がありましたが、これに対する解決策を見つけました。

ここを見てください: https://devforums.Apple.com/message/395049#395049

上記のリンクの内容:


APPNAMEを独自のアプリ名に置き換えてください!

IOS 4.2.1のIM

編集:これまでのところiOS5 + 6 + 7ベータ版での作業

APPNAME-Info.plistUIBackgroundModesを追加し、アプリがオーディオを再生するように選択します

次に、AudioToolBoxフレームワークをフォルダーフレームワークに追加します。

APPNAMEAppDelegate.hに追加:

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

したがって、次のようになります。

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

APPNAMEAppDelegate.mに以下を追加します:

// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];

/* Pick any one of them */
// 1. Overriding the output audio route
//UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
//AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

// 2. Changing the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

2行の前:

[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];

プロジェクトをビルドし、エラーがないかどうかを確認します。そうでない場合は、シミュレータのデバイスに組み込まれたデバイスでデバッグしてみてください。シミュレータでバグが発生する可能性があります。

これが同じ問題を持つ他の人を助けることを願っています。

42
Patrick R

UPDATE IOS 11.2 with Swift 4:

AVPlayerを使用して音楽ファイルを再生している場合は、MPNowPlayingInfoCenter.default()を設定して、ロック画面に再生中の情報を表示する必要があります。

以下のコードは、画面上に再生中のコントロールを表示しますが、コマンドに応答できません。

コントロールも機能させたい場合は、Appleのサンプルプロジェクトをここで確認してください: https://developer.Apple.com/library/content/samplecode/MPRemoteCommandSample/Introduction/Intro.html#//Apple_ref/doc/ uid/TP40017322

Appleのサンプルコードはすべてをカバーしていますが、混乱します。

サウンドを再生してロック画面にコントロールを表示する場合は、これらの手順で問題ありません。

重要な注意:もしあなたが[〜#〜]ではない[〜#〜]AVPlayerを使用してサウンドを再生します。サードパーティのライブラリを使用してサウンドを生成したり、サウンドファイルを再生したりする場合は、コード内のコメントを読む必要があります。また、iOSシミュレーター11.2を使用している場合は、ロック画面にコントロールを表示できません。あなたはそれが動作することを確認するためにデバイスを使用する必要があります。


1-プロジェクトを選択->機能->バックグラウンドモードをオンに設定->オーディオ、AirPlay、Picture in Pictureにチェックを入れます

ios 11 background audio setting

2-AppDelegate.Swiftファイルは次のようになります。

import UIKit

import AVFoundation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        // Override point for customization after application launch.

        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

         //!! IMPORTANT !!
         /*
         If you're using 3rd party libraries to play sound or generate sound you should
         set sample rate manually here.
         Otherwise you wont be able to hear any sound when you lock screen
         */
            //try AVAudioSession.sharedInstance().setPreferredSampleRate(4096)
        }
        catch
        {
            print(error)
        }
        // This will enable to show nowplaying controls on lock screen
        application.beginReceivingRemoteControlEvents()

        return true
    }
}

3-ViewController.Swiftは次のようになります。

import UIKit

import AVFoundation
import MediaPlayer

class ViewController: UIViewController
{

    var player : AVPlayer = AVPlayer()

    override func viewDidLoad()
    {
        super.viewDidLoad()


        let path = Bundle.main.path(forResource: "music", ofType: "mp3")
        let url = URL(fileURLWithPath: path!)

        // !! IMPORTANT !!
        /*
            If you are using 3rd party libraries to play sound 
            or generate sound you should always setNowPlayingInfo 
            before you create your player object.

            right:
            self.setNowPlayingInfo()
            let notAVPlayer = SomePlayer()

            wrong(You won't be able to see any controls on lock screen.):
            let notAVPlayer = SomePlayer()
            self.setNowPlayingInfo()
         */

        self.setNowPlayingInfo()
        self.player = AVPlayer(url: url)

    }


    func setNowPlayingInfo()
    {
        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
        var nowPlayingInfo = nowPlayingInfoCenter.nowPlayingInfo ?? [String: Any]()

        let title = "title"
        let album = "album"
        let artworkData = Data()
        let image = UIImage(data: artworkData) ?? UIImage()
        let artwork = MPMediaItemArtwork(boundsSize: image.size, requestHandler: {  (_) -> UIImage in
            return image
        })

        nowPlayingInfo[MPMediaItemPropertyTitle] = title
        nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = album
        nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork

        nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
    }

    @IBAction func startPlayingButtonPressed(_ sender: Any)
    {
        self.player.play()
    }

古い回答IOS 8.2:

パトリックの答えは完全に正しい。

しかし、私はios 8.2のために何をするかを書きます:

以下のように、アプリのinfo.plistに必要なバックグラウンドモードを追加します。

enter image description here

そして私のAppDelegate.hにこれらのインポートを追加します:

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

次に、AppDelegate.mに次のようにapplication didFinishLaunchingWithOptionsthisと書きました:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

    return YES;
}

画面がロックされていても、アプリは音楽を再生し続けます:)

42
EFE

以下をapplicationDidFinishLaunchingに追加することで、オーディオをバックグラウンドで正常に実行できました

// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];    
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
10
atomoil

iOS 9 Swift

必要なのは、didFinishLaunchingWithOptionsに以下を追加することだけです。

do  {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
    //TODO
}
3
Marcio Arantes

バックグラウンドでもサウンドを再生するGPSバックグラウンドアプリの良い例があります。

http://www.informit.com/articles/article.aspx?p=1646438&seqNum=5

この例では、AudioToolboxが使用されています。

私は自分でテストを行い、機能しました。GPSポスト(UIBackgroundModeslocation)を監視する単純なプロジェクトを作成し、x位置ごとに、次を使用してサウンドを再生します

AudioServicesPlaySystemSound(soundId);

次に、audioUIBackgroundModesの一部として指定すると、アプリケーションがフォアグラウンドでなくなっていても、サウンドが再生されます。

私はそのようなテストをしました、そしてそれは大丈夫です!

(AVPlayerで動作させることができなかったため、AudioToolboxにフォールバックしました)

1
yonel

私は同じ問題を抱えており、Apple Docs: https://developer.Apple.com/library/ios/qa/qa1668/_index.html で解決策を見つけました=

Q:アプリケーションがバックグラウンドにあるときにAV Foundationを使用しているときに、メディアが引き続き再生されるようにするにはどうすればよいですか?

A:バックグラウンドでアプリが可聴コンテンツを再生することを宣言し、オーディオセッションに適切なカテゴリを割り当てる必要があります。特別な ビデオメディアに関する考慮事項 も参照してください。

0
Andriy Savran