Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get current frame canvas #58

Closed
shanytc opened this issue Aug 6, 2015 · 20 comments
Closed

Get current frame canvas #58

shanytc opened this issue Aug 6, 2015 · 20 comments

Comments

@shanytc
Copy link

shanytc commented Aug 6, 2015

Hey @phoboslab

I was wondering if it's possible to get the current frame from the canvas without doing nextFrame() ?
I want to grab the current frame, but everytime i want to get the current frame i have to do something like this:

video_player.seekToFrame(timeline_frame-1,true);
frame_img = video_player.nextFrame();
frame_img .toDataURL('image/webp', 0.7)

i have to go back 1 frame, do nextframe() and then get the current frame.
is it possible to add getCurrentFrame(); alike function?

thanks!

@phoboslab
Copy link
Owner

var currentFrameData = player.canvas.toDataURL('image/webp', 0.7);

@shanytc
Copy link
Author

shanytc commented Aug 6, 2015

oh? awesome!! thanks

@shanytc
Copy link
Author

shanytc commented Aug 9, 2015

@phoboslab
quick question.
I am trying to blend jsmpeg canvas with another canvas drawing like this: (Assuming the frame advances and changes from time to time)

var composite = document.getElementById('composite');
composite.width=1280/2;
composite.height=720/2;
var composite_context = composite.getContext('2d');
composite_context.drawImage(player.canvas,0, 0, composite.width,composite.height);
composite_context.drawImage(canvas,0, 0, composite.width,composite.height); // blend with this 
frame = composite.toDataURL('image/webp', 0.5);

but i am getting black image from the player canvas. any idea what would cause it? thanks!

@phoboslab
Copy link
Owner

I don't understand. I guess player.canvas is the current jsmpeg Canvas, right? What's canvas in your second drawImage() call then?

Note that jsmpeg does not create a new Canvas element for each frame. It uses the same canvas for the whole video. So the "content" of player.canvas changes.

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

player.canvas is the jsmpg object. I want to composite the jsmpg canvas with another canvas. (note that i don't play the movie and then capture, just frame by frame with controls) but for some reason the jsmpg canvas returns black

@phoboslab
Copy link
Owner

Sounds weird. Can you upload a test case?

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

hmmm... i'll see if possible... too much code here!

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

My guess, is that player.canvas.toDataURL('image/webp', 0.7); returns the first frame all the time (which is black in my example since the movie fades in from black to video). and won't update internally even if i play the movie or jump to a specific frame. Maybe you can also check on your end to see if you can grab specific frames?

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

@phoboslab
bug found.
I noticed that in order to get the image (dataURL) from the canvas, I have to player.renderFrame(); first...

but this gives me the "next frame" not the current frame (which returns black - probably the first frame ? or just empty ?)

but this is weird, because I already skipped frames and played the movie and stopped at some frame number, so renderFrame() has already been done.

this means i have to seek a frame backward, renderFrame() and then do the getDataURL... this is a very very slow process :(

solution?

@phoboslab
Copy link
Owner

You have to player.renderFrame() after doing what? When jsmpeg is playing, the canvas holds the current, decoded picture. When you use player.seekToFrame(), the picture is decoded as well.

Which picture do you want? How do you get there?

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

@phoboslab
It's like this:

I have few controls: play, move frame backward -1, move frame forward +1 now, when i play the movie and then pause, i want to save that image. or when i manually step forward/backward i want to save the current displayed image. but everytime i try to save the image i'm getting black image. But as I wrote you above, if for example I'm on frame 55 (already showing the image), then I have to go to frame 54 (seekFrame), then 55 again (renderFrame) in order to save 55 (which works!).

this creates a huge over head on seeking backward 1 frame then forward one frame just to save the current frame that ALREADY has been decoded.

@phoboslab
Copy link
Owner

If you see the frame rendered in the canvas, you should be able to call getDataURL() and get the correct image data. In your example, if you are on frame 55 and the player is showing the image, you shouldn't need to seek or render again to get the data for frame 55.

There's probably something else going on in your code. Upload it somewhere and we can have a look.

@shanytc
Copy link
Author

shanytc commented Aug 13, 2015

yeah that's I thought as well. I am using the github latest jsmpeg. nothing special there. i'll see if i can create a test sample.

@rasmusvhansen
Copy link
Contributor

Actually you can test it on your own site:

  1. Go to http://phoboslab.org/log/2013/05/mpeg1-video-decoder-in-javascript
  2. Run the following snippet in the console
  3. Scroll to the bottom and see the blank image.
var img = document.createElement('img');
img.src = player.canvas.toDataURL('image/webp', 0.7)
img.style.border = '1px solid red';
document.body.appendChild(img);

@dy604
Copy link

dy604 commented Oct 22, 2017

Hi Guys ! I have also met this problem recently . I want to know, how should I get a picture of the current video stream and show the picture on browser ? I attempt above your's method, but the picture is still black, there is nothing, I run this demo on Raspberry follow by this blog https://github.com/phoboslab/jsmpeg#example-setup-for-streaming-raspberry-pi-live-webcam

Is anybody can help me ? @shanytc @phoboslab @rasmusvhansen

Thank you very much !

@dy604
Copy link

dy604 commented Oct 22, 2017

I just want to implement one canvas to show the current video stream and the other canvas can display a frame image at a certain time interval, And then send this frame to the server recognition . But I use player.canvas.toDataURL('image/webp', 0.7) method get a black picture , I don't know why ?

@dy604
Copy link

dy604 commented Oct 22, 2017

This follow is my code:

`// show the current video stream
var canvas = document.getElementById('video-canvas');
var url = 'ws://' + document.location.hostname + ':8082/';
var player = new JSMpeg.Player(url, { canvas: canvas });

// display a frame image at a certain time interval
var pictureCanvas = document.getElementById('picture-canvas');
var context = pictureCanvas.getContext('2d');

// Trigger photo take
function takePhoto() {

    context.drawImage(canvas, 0, 0, 320, 240);

    // var imgData = player.canvas.toDataURL("img/png", 0.1);
    var imgData = canvas.toDataURL('image/webp', 0.7);
            
    $.post('/upload', { img: imgData }, function(ret) {
    });

    setTimeout(takePhoto, 10000);
}


$(document).ready(function() {
    takePhoto();
});

`

@rasmusvhansen
Copy link
Contributor

Did you use the option I introduced in this pull request #106

@dy604
Copy link

dy604 commented Oct 22, 2017

Hi @rasmusvhansen

Thank you very much for your work ! That's very wonderful ! It solved my problem ! It's amazing !

have a good day !

@rasmusvhansen
Copy link
Contributor

You're welcome. Have a good day too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants