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

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.

  • AVCaptureSession stopRunning method creates terrible hang
  • How to capture image without displaying preview in iOS
  • How to set CATextLayer in video according to frame?
  • How to record a video with avfoundation in Swift?
  • AVCaptureVideoPreviewLayer smooth orientation rotation
  • How do I call CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer?
  • The Play/Pause button on the lockscreen works in iOS 5, but not in iOS 6.

    6 Solutions Collect From Internet About “UIWebView: HTML5 audio pauses in iOS 6 when app enters background”

    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

    I work on IOS7.

    It’s work with AVPlayer or AVAudioPlayer. But it’s not work for me with a html5 video in a UIWebView.

    All my code is here.

    • You can paste the code in the AppDelegate of a new empty ios app
    • Add AVFoundation Framework
    • Enable Background Audio
    • I’s does not work, it’s appear in the control center, but music is paused when the app enter in Background!

      #import "AppDelegate.h"
      #import <AVFoundation/AVFoundation.h>
      @implementation AppDelegate
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
          // Override point for customization after application launch.
      
          AVAudioSession *audioSession = [AVAudioSession sharedInstance];
          BOOL ok;
          NSError *setCategoryError = nil;
          ok = [audioSession setCategory:AVAudioSessionCategoryPlayback
                                   error:&setCategoryError];
          if (!ok) {
              NSLog(@"%s setCategoryError=%@", __PRETTY_FUNCTION__, setCategoryError);
          }
      
      
          UIViewController *vc = [[UIViewController alloc] init];
          UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController: vc];
          self.window.rootViewController = nav;
      
      
          //WEBVIEW
          UIWebView *myWeb = [[UIWebView alloc] initWithFrame:CGRectMake(0, 200, 320, vc.view.frame.size.height)];
          myWeb.mediaPlaybackRequiresUserAction = NO;
          myWeb.allowsInlineMediaPlayback = YES;
          [vc.view addSubview:myWeb];
          NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://www.romito.fr/public/inlineHTML5/"]];
          [myWeb loadRequest: request];
      
      
          self.window.backgroundColor = [UIColor whiteColor];
          [self.window makeKeyAndVisible];
          return YES;
      }
      

    The answer from Chris Lundie above is excellent! I have put his block of code inside the AppDelegate of my project and it worked.

    A word of caution:
    1) Be sure you add the framework AVFoundation to your project

    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
    

    Swift Syntax:

    in AppDelegate:

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

    Here the SWIFT 2.0 version to set the audio session category to ‘playback’ before creating the UIWebView.

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    }
    catch let error as NSError {
        print(error)  
    }
    
    do {
        try AVAudioSession.sharedInstance().setActive(true)
    }
    catch let error as NSError {
        print(error)  
    }