33

I see this issue only on the iPad. The same things works as expected on the iPhone.

I am opening the URL from my application in a UIWebView. If the URL is a normal web page, it works fine as expected. But if the URL is that of a remote video/audio file, the UIWebView opens the default player which is again good.

Now when I dismiss the UIWebView (by clicking on the Done button on the player), the streaming doesn't stop and the audio/video keeps playing in the background (I cannot see it but it does keep playing in the background, can hear it). The UIViewController in which the webview was created is also dealloced (I put in a log statement in the dealloc method) but the streaming doesn't stop.

Can someone please help me out on why this could be happening? And how can I stop the audio/video streaming when the UIWebView is closed?

Thanks.

lostInTransit
  • 70,519
  • 61
  • 198
  • 274

11 Answers11

53

I have the same issue as stated but in this case the video that won't stop playing is a Youtube video embeded using the object/embed method.

I spent a long time trying to figure out how to get the video to stop playing and the only solution I found was to tell the UIWebView to load a blank page before dismissing the view:

    [self.webContent loadRequest:NSURLRequestFromString(@"about:blank")];

Edit(2015-05-12): As mentioned by @chibimai below, this answer by alloc_iNit works along the same lines but since my answer is from 5 years ago -- and his only 4 -- the linked answer may be more applicable. I no longer do iPhone dev work so I cannot determine which is better either way.

Community
  • 1
  • 1
nivekastoreth
  • 1,407
  • 13
  • 19
  • thats a workaround albeit a dirty one! Thanks for sharing. Let us know if you find anything else. – lostInTransit May 01 '10 at 03:40
  • 1
    I've modified my original post to show what I'm actually doing. I think I like the "about:blank" approach since it doesn't involve yet more network overhead (especially if it starts trying to fetch resources). – nivekastoreth May 06 '10 at 08:43
  • Could it be that the problem does not exist anymore in iOS 5? – fabb Feb 06 '12 at 11:09
  • I'm on ios5 and this problem still persists – DanZimm May 12 '12 at 19:44
  • I have noticed that in iOS 6 when you try to play an embedded video the media player is opened, instead of the video being played directly inside the page, like it was before. This is an issue for this solution since the blank page opening before closing the web view is now closing the media player, thus preventing the user from seeing the video. – lgdev Oct 09 '12 at 14:22
  • 5
    This post shouldn't be the accepted one. If the video continue to play within the dismissed controller, it's because the controller (or the webview) is not released correctly! Try to add a breakpoint in your dealoc method. Fixing the problem with the solution above is very dirty and will not prevent your app to leak! – Martin Jan 07 '13 at 11:55
  • Kind of shocking that 4 years later this is still an issue. – nivekastoreth Apr 26 '14 at 23:17
  • 2
    look at the accepted answer in this question. That one worked for me. http://stackoverflow.com/questions/7038100/stop-video-in-uiwebview – caribbean May 11 '15 at 08:15
  • 11 Years later, still the same issue – A. Amini May 14 '21 at 14:58
4

I know this is pretty old thread, but for the sake of new developers like me.

My scenario was: I was using split controller, with media list on master and player in the detail controller section

I faced the same issue and tried all sorts of workaround.

I finally figured it out that the problem was simple, I was holding the reference of the detail controller in my master, and was not releasing the earlier detail controller. A simple release in the master at the right place solved the issue.

Dan McClain
  • 11,780
  • 9
  • 47
  • 67
Kalpesh Popat
  • 1,416
  • 14
  • 12
4

I also found this behaviour simply because the web view hadn't been released.

ianjoyner
  • 81
  • 1
2

I'm working on the same problem. I've found that if you define something like this in your script tag:

function stopVideo(){ video.pause(); }
window.onunload = stopVideo;

Then in your UIViewController, add in:

-(void)viewWillDisappear:(BOOL)animated{
    [webView stringByEvaluatingJavaScriptFromString:@"window.onunload();"];
    [super viewWillDisappear:animated];
}

It seems to try to pause/stop the video for several seconds, but then you hear the audio continue to play!


Update!

This is a general bug with the media player. You have to set the playback time to -1 in order to make it really stop.

tolar
  • 37
  • 3
  • the playback time to -1 for what? The video, the webview, somewhere in the settings? appreciate the help – lostInTransit Apr 29 '10 at 04:22
  • 1
    On your HTML5 video object, simply set currentTime to -1 via javascript, ala: function stopVideo(){ video = document.getElementById('myVideo'); video.pause(); video.currentTime = -1; } – tolar Apr 29 '10 at 17:40
  • Thanks, works great where I embed the videos in webviews. But in case I open a video's URL in webview, how can I ensure this works as well? (I just create an NSURLRequest with the URL of the video) – lostInTransit Apr 30 '10 at 04:23
1

In fact, I prefer to use the null link to solve the problem. like this:

[self.webView loadRequest:NSURLRequestFromString(@"about:blank")];
Mi-Creativity
  • 9,554
  • 10
  • 38
  • 47
HaoHuang
  • 11
  • 2
1

I've just had an issues with an mp4 file opening automatically in media player from a web-page without possibility to close it - "Done" button was only seen in video fullscreen mode and just closed fullscreen, so I had no way to return to the webpage without adding a "Back" button to the navigation bar. (on iPhone the video was opening in a separate view with "Done" button taking back to the WebView with the source page)

The workaround that helped me is to open the video file in a separate media player.

catch opening an MP4 file

- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType
{
    NSRange range = [request.URL.absoluteString rangeOfString: @".mp4" options: NSCaseInsensitiveSearch];

    if ( range.location != NSNotFound ) //opening MP4 video file
    {           
        [self showFullscreenMediaWithURL: request.URL];

        return NO;
    }

    return YES;
} 

where

- (void) showFullscreenMediaWithURL: (NSURL *) mediaURL
{
    MPMoviePlayerViewController *ctrl = [[MPMoviePlayerViewController alloc] initWithContentURL: mediaURL];

    ctrl.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentModalViewController: ctrl animated: YES];

    [ctrl release];
}

opens video with URL in a media player in a model view

don't forget to add MediaPlayer.framework to the project and import

#import <MediaPlayer/MediaPlayer.h>

for the project to be built

PS. many thanks to Viktor Gubrienko for the solution

0

thanks to your thread on this issue I was able to figure out a solution that resolves the issue completely, and I tested it on my IPad, not just the simulator. This also resolves the issue with the audio playing. This is not the permanent resolution but an effective work around.

Overview of the approach:

Basically all that is needed is to send a short audio file to the webView. I made a copy of the IMac submarine.m4v file, I called ping.m4v and added it to my xcode project in the resource folder.

Then at the point when I want the video / audio to stop I do the following steps:

webView.hidden = TRUE;
NSString *mimeType = [[NSString alloc] initWithString:@"video/x-m4v"];
NSData *PingData = [NSData alloc];
PingData = [NSData dataWithContentsOfFile:PingFilePath];

[webView loadData:PingData MIMEType:mimeType textEncodingName:nil baseURL:[NSURL URLWithString:PingFilePath]];

Now you also have to handle error "204". Error 204 seems to be just a warning saying that webView is going to handle this audio file. To handle the error I added this single line (see >>>) to didFailLoadWithError

(void)webView:(UIWebView *)BHwebView didFailLoadWithError:(NSError *)error
{

    NSLog(@"Error %i", error.code);
    if (error.code == NSURLErrorCancelled) return; // this is Error -999    
        if (error.code == 204) return; // this is Error 204 - for audio player in webview.

Finally I turn webView.hidden = FALSE right before I display my next Audio/Video. This way the little play bar for the sound file does not show on the display. There is just a soft ping sound... any audio file will do...

I hope this helps...

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
0

This is what I use. It does log this error "Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session." but does stop the audio file from playing (fading out) and remembers the play position.

AVAudioSession *s = [AVAudioSession sharedInstance];
if (s != nil)
    [s setActive:NO error:nil];
K1w1Geek
  • 605
  • 5
  • 5
0

As web view hadn't been released, the video keeps playing on the web view in background.

So you need to release the web view simply by using below code which works fine for me.

- (void)viewDidDisappear:(BOOL)animated 
{
    [super viewDidDisappear:(BOOL)animated];
    [self.wvwebview removeFromSuperview];
}

I hope this helps...

0

in my case using loadHTMLString and not loadRequest with @"about:blank", fix the problem on macOS

 [self.wkWebView loadHTMLString:@"about:blank" baseURL:nil];
user1105951
  • 2,259
  • 2
  • 34
  • 55
0

I had the same issue in Table view where the table view cell has a webview which loads an audio file . Once you play and go back to another screen the audio still plays .

Solution : reload the table view in viewWillDisappear(_:) of the table view controller and the audio will stop playing once you navigate to another screen .

Sateesh Pasala
  • 772
  • 8
  • 15