UIWebView: HTML5 audio pauses in iOS 6 when app enters background

20,756

Solution 1

Starting with iOS 6, you MUST set the audio session category to 'playback' before creating the UIWebView. This is all you have to do. It is not necessary to make the session active.

This should be used for html video as well, because if you don't configure the session, your video will be muted when the ringer switch is off.

#import <AVFoundation/AVFoundation.h>

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL ok;
NSError *setCategoryError = nil;
ok = [audioSession setCategory:AVAudioSessionCategoryPlayback
                         error:&setCategoryError];
if (!ok) {
  NSLog(@"%s setCategoryError=%@", __PRETTY_FUNCTION__, setCategoryError);
}

Ensure that your target links to the AVFoundation framework.


If using Cordova, the file you need to modify is platforms/ios/MyApp/Classes/AppDelegate.m, and will end up looking like this:

#import "AppDelegate.h"
#import "MainViewController.h"
#import <AVFoundation/AVFoundation.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    BOOL ok;
    NSError *setCategoryError = nil;
    ok = [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
    if (!ok) {
        NSLog(@"%s setCategoryError=%@", __PRETTY_FUNCTION__, setCategoryError);
    }

    self.viewController = [[MainViewController alloc] init];
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Also, as mentioned in the comments, you need to link the AVFoundation Framework, as explained in this answer:

  • Open your project with xcode open ./platforms/ios/MyApp.xcworkspace/
  • Project navigator > target My App > General
  • Scroll to the bottom to find Linked Frameworks and Libraries

Solution 2

Swift Syntax:

in AppDelegate:

import AVFoundation

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  do{
      let audio = AVAudioSession.sharedInstance()
      try audio.setCategory(AVAudioSession.Category.playback)
  }catch let error as NSError{
     print(error)
  }
}

Solution 3

This plugin will make your app ignore the mute switch. It's basically the same code that's in the other answers but it's nicely wrapped into a plugin so that you don't have to do any manual objective c edits.

https://github.com/EddyVerbruggen/cordova-plugin-backgroundaudio

Run this command to add it to your project:

cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-backgroundaudio.git
Share:
20,756

Related videos on Youtube

heysamhey
Author by

heysamhey

Updated on July 09, 2022

Comments

  • heysamhey
    heysamhey almost 2 years

    Good day,

    My app is a music playing app. I control the <audio>-Tag with Javascript. So far no problems, play, pause, next and previous buttons are working. When I stand-by the device in iOS 5, the music keeps playing, but the automatic next song doesn't work. When it isn't in stand-by, it works. And in iOS 6, just after pressing the button, the music fades out.

    The Play/Pause button on the lockscreen works in iOS 5, but not in iOS 6.

    • BoltClock
      BoltClock almost 12 years
      Perhaps wait and see if they fix it in a later build?
    • heysamhey
      heysamhey almost 12 years
      Maybe it's a feature, not a bug?
  • strawtarget
    strawtarget almost 12 years
    Wow, this appears to be related to a similar problem I'm having. Where did you find this out? Is there documentation anywhere about what changed in iOS6 with UIWebView / AVAudioSession?
  • Chris Lundie
    Chris Lundie almost 12 years
    The iOS 6 release notes say that UIWebView does not set the audio playback session anymore, so you must do it yourself. The note was possibly only added in the GM release. At least, I had this problem during the beta period but didn't find a fix until the GM.
  • heysamhey
    heysamhey over 11 years
    I've never done any Objective-C and have no idea what i should do with this code snippet, could you explan to me?
  • ySgPjx
    ySgPjx over 11 years
    Is it necessary to do it before the webview is created, or can it be done later when the playback has started?
  • block14
    block14 over 10 years
    @heysamhey this code can be placed in ViewController.m. The import statement should go at the top, and the rest can go in viewDidLoad. To link the AVFoundation framework, check this answer on SO.
  • Danil
    Danil over 10 years
    How to prevent pausing a video burring switching to background?
  • bk138
    bk138 about 9 years
    @ChrisLundie maybe you should add that audio background mode needs to be enabled in XCode capabilities tab as well. Just for completeness' sake :-)
  • kdpnz
    kdpnz over 8 years
    Previously, this solution had worked perfectly for me in every Cordova app. But it seems that Cordova iOS 4.0.1 may have done something to break this, because I've used the exact same code but the background audio still doesn't function. To remedy this, I've instead just used a background audio plugin, which doesn't require manual entry of class files: npmjs.com/package/nl.kingsquare.cordova.background-audio
  • JDev
    JDev over 7 years
    Is there any such method for inline videos that can play audio when the app enters the background. Currently, when the app enters the background, the audio stops playing. However, I can pull up Control Centre and continue playing at any time.
  • MGRM
    MGRM about 4 years
    Is this workaround still work in the latest iOS 13.4.1?