xat / castnow

commandline chromecast player
MIT License
3.81k stars 243 forks source link

Constantly buffering when transcoding #45

Open mynameisfiber opened 9 years ago

mynameisfiber commented 9 years ago

Whenever I cast a file with the --tomp4 option, the state constantly says "Buffering..." even though the video is playing smoothly. In addition, this doesn't let me use any of the key-bindings to pause or seek.

$ uname -a
Linux electron 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt2-1 (2014-12-08) x86_64 GNU/Linux
$ ffmpeg --version
ffmpeg version 2.5.1 Copyright (c) 2000-2014 the FFmpeg developers
  built on Dec 16 2014 08:05:21 with gcc 4.9.2 (Debian 4.9.2-8)
xat commented 9 years ago

Yes, the controls are currently disabled in trancode mode (it's also mentioned in the README). The transcoding is done 'on the fly'. I'm planning on adding a temp file as buffer in between. With that in place at least pause/play should work again.

mynameisfiber commented 9 years ago

Hrmm... well I'm not sure how easy javascript async IO is to fanagle, but if you just read in the output of ffmpeg into a limited sized, in memory, buffer and played from there you'd be fine. When playback is paused and the transcoding fills up the buffer (which would stop reads from your subprocess), ffmpeg would block until another read on that pipe happened.

As a test I created a fifo (just by using mkfifo so it has the standard 65336 byte capacity) and filling it with a transcoded file by running ffmpeg. After transcoding for a couple seconds, I ran castnow on the fifo and things worked perfectly. When I paused playback the fifo filled up and transcoding paused and once I resumed playback transcoding also resumed in order to fill up the pipe.

I'll try looking at the code later today, but javascript is gibberish to me!

xat commented 9 years ago

That sounds cool! I would definitly prefer a small fifo buffer over an temp file if that does the job. I'm currently on holiday with no hdmi capable TV so testing this is quite hard atm :)

xat commented 9 years ago

@mynameisfiber Can you give me some advice how you got this running with mkfifo? I tried it like this, but had no luck:

mkfifo pipe.mp4
ffmpeg -i samples/test.mp4 -vcodec h264 -f mp4 -movflags frag_keyframe+faststart -strict experimental pipe:1 > pipe.mp4
castnow ./pipe.mp4

The pipe.mp4 stays at a filesize of 0.

parshap commented 9 years ago

@xat I don't think a named pipe is necessary for this. Node streams should take care of this for you automatically.

When you send a pause command to Chromecast, Chromecast should stop reading from the http socket. This will cause the res stream in node to fill up its internal buffer (as the ffmpeg stream continues to write to it) which will then apply back pressure to ffmpeg and cause it to block as @mynameisfiber describes above.

You can also manually control back pressure by using stream.pause() and stream.resume().

This should work in theory. I haven't really tested this out and am not near a Chromecast to do so right now. However, in my experience pausing transcoded streams seems to work just fine. (Seeking does not, of course.)

xat commented 9 years ago

@parshap Yes, I also would have thought that this should just work by piping the the output of ffmpeg to the response. However, once you hit pause the video gets stuck and your not able to resume it again. Thats why I was interested in seeing if it really works when creating the buffer with mkfifo.

xat commented 9 years ago

@parshap Since you mentioned seeking, we had some thoughts on that over here https://github.com/xat/chromecast-scanner/issues/2 (but I also don't think we will get this to work atm)

parshap commented 9 years ago

I've created a new issue to discuss playback control of transcoded files: #58.

Sorry for creating yet another issue but hopefully this will get the conversation going in one place. Feel free to close the new issue if you think otherwise.

xat commented 9 years ago

+1 makes perfectly sense to bundle the discussions around this topic at one place.

ldmldmldm commented 9 years ago

Hi. When I castnow a .mkv file the video playback is smooth however I get no audio. When I use --tomp4 the audio works however the video buffers (for like 15 secs) every 5 seconds, it's not watchable. The video file is on the machine doing the transcoding, and the machine is definitely powerful enough.

$ uname-a
Linux arch 3.19.3-3-ARCH ...
$ ffmpeg -version
ffmpeg version 2.6.1 ...

Update: using --ffmpeg-ac 2 reduces the amount of buffering occurrences by about half, but it's still not enough to be watchable.

Update: using --ffmpeg-vc copy does not resolve the issue.