Summary: | REGRESSION (Safari 9): drawImage doesn't paint the current frame of a video | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | @fregante <bugs> | ||||||||
Component: | Canvas | Assignee: | Nobody <webkit-unassigned> | ||||||||
Status: | NEW --- | ||||||||||
Severity: | Normal | CC: | acrong3, calipoop, dbates, denny.ferrassoli, dino, electroteque, eric.carlson, gruan, info, jer.noble, justin.hamm, lucas, mail, marc.tremblay, masotime, simon.fraser, sinagra, solo, staffan.klashed, webkit-bug-importer | ||||||||
Priority: | P2 | Keywords: | InRadar | ||||||||
Version: | Safari 9 | ||||||||||
Hardware: | Mac | ||||||||||
OS: | OS X 10.11 | ||||||||||
Attachments: |
|
Description
@fregante
2016-01-28 03:56:10 PST
I cannot reproduce this using the attached test case in Safari 9.0.3 on El Capitan. Please try again, other people are experiencing it. http://stackoverflow.com/questions/35060414/safari-9-paints-only-the-first-frame-of-a-video-on-canvas-bug Also getting this bug... It seems to be very intermittent, and takes multiple refreshes sometimes for the bug to occur. In addition if multiple browser tabs are open with the attached example, and one tab has the issue after a refresh, it will affect the other tab. I've only managed to catch this bug live once, in a shipping version of Safari. Some dtrace debugging showed that MediaPlayerPrivateAVFoundationObjC::videoOutputHasAvailableFrame() was repeatedly returning false, due to [m_videoOutput hasNewPixelBufferForItemTime:[m_avPlayerItem currentTime]] returning NO. <http://trac.webkit.org/browser/trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm#L2204> Tested Federico's test case using Safari 9.0.3 on El Capitan (10.11.3) and it only ever draws the first frame. This is the same behavior I see everywhere else that I try to draw a frame of video to a canvas. The only exception I have found is Apple's Listing 17-2 Breaking video into tiles from https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/PuttingVideoonCanvas/PuttingVideoonCanvas.html - note that the embedded example is a rendered movie. If I drop that code in a file, it works reliably with the same config as above. One caveat may be that I've only tested with a video that is bigger than the one in Apple demo and haven't adjusted the code, so only a part of the larger video is being tiled/rotated. I am having similar issues drawing a canvas on another canvas with simple drawImage canvas.drawImage(canvas2,0,0); It works on all browsers but not Safari 9 on Mavericks, neither IOS9 BUT ... if i resize the browser ... tadaa ... the problem is magically fixed !! WTF ?? I'm using Safari (Version 9.1.1 (11601.6.17)) on Mac OS El Capitan (10.11.5 (15F34)) And when I open this example, I can only pain the 1st frame of the video. http://jsfiddle.net/on1kh4o0/422/ Is there any work around? Created attachment 279912 [details]
Test case to reproduce bug
vid2.mov in video source is Big Buck Bunny short movie.
Bug does not reproduce every time 100%. But, should after a number of refreshes.
Existing test case media/video-canvas-drawing-output.html shows the bug, but does not catch it because it is looking at pixels that do not change between frames. This is a known issue and requires drawing twice. Simply before doing the real draw and capture context.drawImage(video, 0, 0); Call this with a 1 second delay before capturing again. var canvas = this.createCanvas(), context = canvas.getContext("2d"); context.drawImage(container, 0, 0); this.clearCanvas(canvas); setTimeout(function() { onSuccess(container); }, 1000); Saying that you still need to use a CORS proxy for Safari so bring up a second stream and seek, then pre capture then do the real capture. Alot of mucking around for Safari. Even with mediasource it requires the same reloading of the stream and seeking. So you don't exactly need to use the same canvas just a temporary one. It's something to do with the mediaelement just like the nasty cors bug that is breaking 360 video rendering. Created attachment 282814 [details]
Fully Self-contained bug reproduction
A fully self-contained HTML file with a video encoded as a base64 data URL to reproduce the issue.
I've successfully reproduced the issue in a consistent way, with the newly uploaded HTML file I've added. If you hide the video player and start playing it, then the video capture works fine. Also, playing, pausing, switching to another tab then switching back seem to "refresh" the video and fix the issue. This is a definite bug, please fix it. I was able to consistently reproduce this bug on OSX 10.11.3 with Safari 9.0.3. Switching to a new desktop and back to the one with Safari and then calling drawImage will work properly. I am also experiencing the same issue on Safari 9.0.3 & Mac OS 10.11.3l (El Capitan). The previous examples all show the issue. Switching desktop, going fullscreen or switching browser tab before copying the video will result in the correct frame. I have not found any way to workaround the issue. I tried two of the test cases above with Safari 10.0 and the capture is working. I'm on 10.11.6 and Safari 10.0 (11602.1.50.0.10). Anyone else verify this? (In reply to comment #17) > I tried two of the test cases above with Safari 10.0 and the capture is > working. I'm on 10.11.6 and Safari 10.0 (11602.1.50.0.10). > > Anyone else verify this? I still experience the same issues on OS X 10.11.6 (15G1004), Safari 10.0 (11602.1.50.0.10). I am however not able to reproduce the issue consistently. Some times capture works, sometimes it doesn't. It was easiest reproduced by repeatedly reloading the JSFiddle posted earlier (http://jsfiddle.net/on1kh4o0/422/) and checking if the canvas to the right played back the video. For those of you who are able to consistently reproduce, would you please gather a sysdiagnose while reproducing, attach that sysdiagnose to a new Radar at bugreport.apple.com, and then send me the Radar #? This is likely an underlying OS issue and the sysdiagnose will have valuable logs for figuring out what is going on. Any update on this? It's still an issue, and very troublesome given that it's intermittent and there doesn't appear to be a work-around... call draw image then a timeout then draw image again for Safari. It stops the black frame issue. Here is an es6 util of mine before I do the actual capture preCapture(container, onSuccess) { const canvas = this.createCanvas(), context = canvas.getContext("2d"); context.drawImage(container, 0, 0); this.clearCanvas(canvas); setTimeout(() => { onSuccess(container); }, 1000); } Maybe its only required once no idea. I've become a master of finding work around for all these faulty webkit flaws. I even copped abuse on one ticket for eventually reporting a work around in that ticket and telling them not to bother after months of no response hahah. (In reply to comment #21) > call draw image then a timeout then draw image again for Safari. It stops > the black frame issue. > > Here is an es6 util of mine before I do the actual capture > > preCapture(container, onSuccess) { > const canvas = this.createCanvas(), > context = canvas.getContext("2d"); > context.drawImage(container, 0, 0); > this.clearCanvas(canvas); > > setTimeout(() => { > onSuccess(container); > }, 1000); > } > > Maybe its only required once no idea. > > I've become a master of finding work around for all these faulty webkit > flaws. > > I even copped abuse on one ticket for eventually reporting a work around in > that ticket and telling them not to bother after months of no response hahah. Thanks for the tip - I'll give it a whirl. I am encountering this bug on Safari on iOS 13.3.1, when attempting to capture a video poster at a user-defined currentTime by rendering video into a canvas + toDataURL. It reliably happens if the video file's EXIF rotation is non-zero. Any thoughts? |