簡體   English   中英

如何讓我的 AVPlayer 在應用程序處於后台時播放?

[英]How do I get my AVPlayer to play while app is in background?

我已經完成了我的功課......一直在這里閱讀,文檔,谷歌搜索,stackoverflowing......但是當用戶讓應用程序進入后台時,我的聲音仍然沒有運氣。

到目前為止我所做的:將 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 構建它。

有人對我應該做什么有任何建議嗎?

使用Swift 4更新IOS 11.2:

現在,如果您使用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和畫中畫

ios 11背景音頻設置

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()
    }

OLD ANSWER IOS 8.2:

帕特里克的回答是完全正確的。

但是我要寫我為ios 8.2做的事情:

我添加了我的應用程序的info.plist所需的背景模式,如下所示:

在此輸入圖像描述

在我的AppDelegate.h中,我添加了這些導入:

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

然后在我的AppDelegate.m中,我寫了應用程序didFinishLaunchingWithOptionsthis,如下所示:

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

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

    return YES;
}

現在App即使屏幕被鎖定也會繼續播放音樂:)

有同樣的問題,但找到了解決方案..

請看這里: https//devforums.apple.com/message/395049#395049

以上鏈接的內容:


用您自己的應用名稱替換APPNAME

我在iOS 4.2.1上

編輯:到目前為止使用iOS5 + 6 + 7測試版

APPNAME-Info.plist添加UIBackgroundModes ,選擇App播放音頻

然后將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 {

但在兩行之前:

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

構建你的項目,看看是否有任何錯誤,如果沒有,嘗試在模擬器的設備上調試,它可以在模擬器上出錯。

希望這有助於其他同樣的問題..

我通過在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];

iOS 9 Swift

您應該只需要將以下內容添加到didFinishLaunchingWithOptions中

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

你有一個很好的GPS背景應用程序示例,即使在后台播放聲音:

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

在此示例中,使用了AudioToolbox。

我自己做了一個測試並且它有效:創建一個監視GPS帖子( UIBackgroundModes location )的簡單項目,以及每個x接收位置,播放聲音使用

AudioServicesPlaySystemSound(soundId);

然后,如果您將audio作為UIBackgroundModes一部分並且將播放聲音,即使應用程序不再處於前台。

我做了這樣的測試,它運作正常!

(我沒有設法讓它與AVPlayer一起使用,所以我退回到AudioToolbox)

我遇到了同樣的問題,我在Apple Docs中找到了解決方案: https//developer.apple.com/library/ios/qa/qa1668/_index.html

問:在應用程序處於后台時,如何確保在使用AV Foundation時我的媒體將繼續播放?

答:您必須聲明您的應用程序在后台播放可聽內容,並為您的音頻會話分配適當的類別。 另請參閱視頻媒體的特殊注意事項

Swift 5工作

以下是我為讓 avPlayer 正在播放的視頻在后台播放音樂而做的 4 件事。 我按照@AndriySavran 的回答中的 Apple 方向鏈接以及其他一些內容進行操作。

1- 在 AppDelegate 的didFinishLaunching我放了:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers, .allowAirPlay])
            print("Playback OK")
            try AVAudioSession.sharedInstance().setActive(true)
            print("Session is Active")
        } catch {
            print(error)
        }

    // whatever other code that you use ...

    return true
}

2- 按照@LeoDabus 的回答進行操作。 在您的Signing & Capabilties > Background Modes (如果背景模式不存在,然后從功能中選擇它)> 勾選Audio, Airplay, and Picture in Picture

3- 在具有AVPlayer的視圖控制器中,添加.didEnterBackgroundNotification.willEnterForegroundNotification通知

var player: AVPlayer?
var playerItem: AVPlayerItem? // your AVPlayer should be initialized with this

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(appDidEnterBackground),
                                           name: UIApplication.didEnterBackgroundNotification, object: nil)
    
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(appWillEnterForeground),
                                           name: UIApplication.willEnterForegroundNotification, object: nil)

}

4- 為選擇器方法添加來自 Apple 鏈接的代碼

@objc func appDidEnterBackground() {

    if let player = player {
        if !player.isPlaying { // if the player isn't playing no need to disable the playerItemTrack
            return
        }
    }

    guard let tracks = playerItem?.tracks else { return } // this is assuming your AVPlayer is initialized with a class property AVPlayerItem like from step 3

    for playerItemTrack in tracks {
        
        guard let assetTrack = playerItemTrack.assetTrack else { continue }
        
        // Find the video tracks.
        if assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
     
            // Disable the track.
            playerItemTrack.isEnabled = false
        }
    }
}

@objc func appWillEnterForeground() {
    
    guard let tracks = playerItem?.tracks else { return }

    for playerItemTrack in tracks {
        
        guard let assetTrack = playerItemTrack.assetTrack else { continue }
        
        // Find the video tracks.
        if assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
     
            // Enable the track.
            playerItemTrack.isEnabled = true
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM