4

In my fun project, I'm downloading video file from youtube, and writing to a file on local disk. Simultaneously I want to play it. The objective is to cache the file on local disk, so that when I want to see the video again, the app can play it locally, thereby saving bandwidth.

I'm using Python 3.3.1, PyQt4/Phonon and LibVLC. So far, I'm able to do the following things:

  • Given a youtube watch url, I can download the video file and then play it using both PyQt4/Phonon and LibVLC, independently. It is not streaming.

  • Since LibVLC supports streaming, I'm able to play the given url through streaming.

The second is very close to what I want to do, but since it doesn't save the file on disk, next time I cannot play the same video locally.

I'm looking for some guidelines as to how to proceed from here. In particular, how to play a video from an incomplete file which is still being written into.

I'm completely fine with any API (that does the job) as long as it is:

  • Python 3.3.1 (preferably)
  • C
  • C++.

And I'm looking for alternative approaches also, if my current approach is not correct or makes the problem more difficult than it actually is.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • You may want to look into ffmpeg. It will allow you to both display and write to a file. But I'm not sure how you can reneder it on PyOt4. There is a famous tutorial http://dranger.com/ffmpeg/ to get started with. The input file can be changed to url instead of reading from file. – praks411 May 12 '13 at 10:59
  • ffmpeg is quite a broad term, more specifically you'll want to look into [libav](http://libav.org/) and its [libavcodec](http://www.ffmpeg.org/libavcodec.html)(for decoding the demuxed stream) and [libavformat](http://www.ffmpeg.org/libavformat.html)(for demuxing the stream) components. libav's [download page](http://libav.org/download.html), win64 nightlies [download page](http://win32.libav.org/win64/?C=M;O=D), [documentation](http://libav.org/documentation.html) and [examples](http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html). – Edward A May 12 '13 at 11:13
  • I have managed to do something similar with GStreamer. It has a [tee](http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-tee.html) element which can be used to split the pipeline into multiple output channels. – StackedCrooked May 12 '13 at 11:22
  • @StackedCrooked: Could you elaborate on that? – Nawaz May 12 '13 at 11:28
  • @Nawaz I'm sorry but's not trivial to explain. You should read the first 10 chapters of the GStreamer manual to get a basic idea. (Don't worry, this only takes 30 minutes or so.) – StackedCrooked May 12 '13 at 11:50
  • Can't libVLC write the file while streaming it? The VLC app certainly can. – abarnert May 12 '13 at 12:29
  • @abarnert: I don't know. Do you have any idea how it does it? – Nawaz May 12 '13 at 12:30
  • Also, what happens when you try to play the partial file with Phonon or libVLC? Does it give you an error? Fail to play? (Keep in mind that some file containers—most notably MPEG4—can put index information anywhere in the file, even at the end, and "stream" players may know how to deal with this, while "file" players will not…) – abarnert May 12 '13 at 12:31
  • @Nawaz: I don't know libVLC that well. Conceptually, it's simple to save a stream at the same time as you play it; as far as what actual API methods the VLC client uses to do it, I have no idea. – abarnert May 12 '13 at 12:32
  • @StackedCrooked: There are too many references/docs/tutorials out there. Which one should I read? [this](http://docs.gstreamer.com/display/GstSDK/Basic+tutorials), [this](http://docs.gstreamer.com/display/GstSDK/Playback+tutorials) or [this](http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/index.html)? There are [other links](http://gstreamer.freedesktop.org/documentation/) also. – Nawaz May 12 '13 at 12:38
  • @Nawaz [This one.](http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/index.html) – StackedCrooked May 12 '13 at 14:48
  • @StackedCrooked: Yes. I was reading that. BTW, I'm thinking of an alternative: what if `thread1` (which downloads the file) acts as server, and `thread2` acts as a client, then *maybe* I could make it look like streaming and therefore LibVLC would able to play it. Is this approach doable? – Nawaz May 12 '13 at 14:54
  • @Nawaz I think it's doable if you're willing to "get your hands dirty" :) – StackedCrooked May 12 '13 at 16:04
  • @Nawaz Hi! as you says: *`Since LibVLC supports streaming, I'm able to play the given url through streaming.`* today I need to measure [QoE/QoS](http://en.wikipedia.org/wiki/Quality_of_service) for online video, Can we use VLC library for this purpose, I just need to measure speed of steaming. Can you help me on this, or give me some idea? – Grijesh Chauhan May 13 '13 at 06:00
  • @GrijeshChauhan: I've no idea. I've just started exploring LibVLC. You might want to explore VLC player also? Maybe it can help you some way. :-) – Nawaz May 13 '13 at 06:10
  • @Nawaz Thanks for replay Nawaz!, I just read your [this question](http://stackoverflow.com/questions/16515099/saving-a-stream-while-playing-it-using-libvlc?lq=1), In this you says that *"you are able to save the video stream to a file"* from a URL, I think your video don't runs because you are saving packets in file out-of-order. – Grijesh Chauhan May 13 '13 at 06:27
  • @GrijeshChauhan: "saving packets in file out-of-order" ? What does that mean? Can you comment on that question itself so others can see and comment further? – Nawaz May 13 '13 at 06:44
  • @Nawaz I have fuzzy guess that because you file `example.mpg` is corrupt, `media_player_new()` couldn't run the file. You may download one .mpg file and `vlc.Instance()` that file. Anyways I am not sure that why I didn't add my comment there to your question, Sorry Man..And thanks for replay! :) – Grijesh Chauhan May 13 '13 at 07:15
  • @StackedCrooked: I'm back to this thing again. I've installed gstreamer-1.0 on my Ubuntu 14.04 but I'm unable to find any struct named as `GstTee`. Where should it be located at? Do I need to install anything else? – Nawaz Sep 03 '14 at 14:43

1 Answers1

1

VLC supports playback of incomplete files, so if you're up for a bit of non-blocking I/O and/or parallel code, you should be able to start the download and after a sufficient amount has been written, use LibVLC to start playback. Depending on what compression algorithm is used, you may need to buffer enough so that there's always several seconds of data left in the buffer -- if I recall correctly, some of the more modern algorithms record deltas and index information going forward and backward.

You may get a few warnings / error messages / Exceptions, but I would not assume that they're fatal -- let the playback quality be your guide!

This is somewhat similar to some of the suggestions from the comments above, and is also related to a lot of what @abarnert said, to a lesser extent some of the exchange with @StackedCrooked.

Livius
  • 3,240
  • 1
  • 17
  • 28
  • Is this approach safe? I mean if the buffering is slower than the rate of consumption by VLC player, then soon there will no buffer and the player will stop. Would it *resume* playing if there comes more buffer within few seconds? – Nawaz May 14 '13 at 10:00
  • @Nawaz It should be safe from a security standpoint -- VLC has to be able to deal with streaming and corrupt files, and an incomplete file is ultimately a corrupt file. More generally, the buffering issue is one you're going to have no matter what. I'm not sure if VLC will resume playback on its own, but assuming libVLC throws an exception or terminates playback too soon, you can buffer up and resume playback from the last known good position (which means you will have to track position if it's not included in the exception.) The easiest solution is of course to buffer more initially. – Livius May 14 '13 at 10:29
  • Sounds reasonable. +1 :-) (BTW, it would be good if you edit the answer, adding what you said in the comment in response to mine). – Nawaz May 14 '13 at 11:39