orithena / youtupi

YouTube (mobile) web frontend for your Raspberry Pi
http://blog.maxtuni.es/2013/02/introducing-youtupi-youtube-mobile-web.html
2 stars 0 forks source link

Doesn't seem to pull the highest quality youtube videos #2

Open nzurku opened 7 years ago

nzurku commented 7 years ago

I'm not sure if this is somehow caused by my side, but when I open a youtube video it seems to be approximately 480p. I've ensured the GUI is set to "highest quality" but is there any way to verify what video quality it is pulling, versus all the options that are available?

Thanks!

orithena commented 7 years ago

This part of the code is written by @kktuax and/or hidden in a library, so I did not verify whether it really does fetch the highest available quality.

To verify the available data fetched from youtube, you may insert a printing statement to the getUrl function in youtupi/modules/youtube.py.

First, add betterprint to the imports:

from betterprint import pprint

then print the data blob just after printing "Locating URL...":

print 'Locating URL for: ' + data['id']
pprint(data)

Then, stop the youtupi service and run it from the command line. On adding a video to the playlist, it should print out the whole data blob received from youtube including all available formats and qualities.

Remember that there are some videos on youtube that are not available in HD because the uploader didn't have better source material.

orithena commented 7 years ago

Okay, I now tried it myself.

First, my code from above is not that helpful -- I suggested the wrong position in the code.

Insert the print statements after best = video.getbest in getUrl:

    best = video.getbest(preftype="mp4")
    print("Available streams:")
    pprint(data)
    print("Chosen stream:")
    pprint(best._info)

Or, if you don't want too much information printed:

    best = video.getbest(preftype="mp4")
    print "\n".join(["Type: %s  Resolution: %s  Audio: %s  Video: %s" % (x._info['ext'], x.resolution, x._info['acodec'], x._info['vcodec']) for x in video._allstreams])
    print "Chosen stream: ", "Type: %s  Resolution: %s  Audio: %s  Video: %s" % (best._info['ext'], best.resolution, best._info['acodec'], best._info['vcodec'])

Results of my tests: You're right, it does not retrieve the best quality available. But it does retrieve the best quality file available that contains both audio AND video. It seems that some players are able to work with two independent streams for audio and video -- omxplayer, sadly, is not among them (as far as I know).

Looks like this is unfixable on a Raspberry Pi, unless omxplayer learns to utilize DASH streams or we find a hack to retrieve both DASH streams and mux them into a format that's palatable for omxplayer.

nzurku commented 7 years ago

Thanks for the replies, I'm a little busy right now so I can't dig in myself with your diagnostic code, but I'll hopefully be able to do so on Monday to help out.

Example of the issue:

If you do the youtube-dl manually and open the link in omxplayer, you'll see much better quality than if you use youtupi.

Here is the link to a test video: https://www.youtube.com/watch?v=4kX90HzA0FM Open that in Youtupi and notice the quality.

Now manually you can run this: sudo youtube-dl -g https://www.youtube.com/watch?v=4kX90HzA0FM omxplayer -o hdmi "$manually_add_output_of_above_command_here"

Much higher quality on that manual method.

I assumed the project you were using to pull YouTube videos simply automated those manual steps, but there must be an issue somewhere that it's not doing it properly.

Don't quote me on this because I haven't tested it again - but I believe the version by @kktuax doesn't have this issue.

Thanks again for even looking at this, I really like this project and how you've forked it.

orithena commented 7 years ago

I just tested the exact video you mentioned while having the above printing statements active. This is what I got:

Type: webm  Resolution: 0x0  Audio: opus  Video: none
Type: webm  Resolution: 0x0  Audio: opus  Video: none
Type: m4a  Resolution: 0x0  Audio: mp4a.40.2  Video: none
Type: webm  Resolution: 0x0  Audio: vorbis  Video: none
Type: webm  Resolution: 0x0  Audio: opus  Video: none
Type: webm  Resolution: 256x144  Audio: none  Video: vp9
Type: mp4  Resolution: 256x144  Audio: none  Video: avc1.4d400c
Type: webm  Resolution: 426x240  Audio: none  Video: vp9
Type: mp4  Resolution: 426x240  Audio: none  Video: avc1.4d4015
Type: webm  Resolution: 640x360  Audio: none  Video: vp9
Type: mp4  Resolution: 640x360  Audio: none  Video: avc1.4d401e
Type: webm  Resolution: 854x480  Audio: none  Video: vp9
Type: mp4  Resolution: 854x480  Audio: none  Video: avc1.4d401f
Type: mp4  Resolution: 1280x720  Audio: none  Video: avc1.4d401f
Type: webm  Resolution: 1280x720  Audio: none  Video: vp9
Type: mp4  Resolution: 1920x1080  Audio: none  Video: avc1.640028
Type: webm  Resolution: 1920x1080  Audio: none  Video: vp9
Type: 3gp  Resolution: 176x144  Audio:  mp4a.40.2  Video: mp4v.20.3
Type: 3gp  Resolution: 320x180  Audio:  mp4a.40.2  Video: mp4v.20.3
Type: webm  Resolution: 640x360  Audio:  vorbis  Video: vp8.0
Type: mp4  Resolution: 640x360  Audio:  mp4a.40.2  Video: avc1.42001E
Type: mp4  Resolution: 1280x720  Audio:  mp4a.40.2  Video: avc1.64001F
Chosen:  Type: mp4  Resolution: 1280x720  Audio:  mp4a.40.2  Video: avc1.64001F

So... it does work here with 720p. I also do believe that I did not change anything in the server-side code that might change the quality setting.

But, it being javascript, there might be something in the front-end code. I'd need a line from the youtupi output that looks like this:

{{"id":"4kX90HzA0FM","description":"Pilfering Passwords with the USB Rubber Ducky Can you social engineer your target into plugging in a USB drive? How about distracting 'em for the briefest of ...","title":"15 Second Password Hack, Mr. Robot Style - Hak5 2101","thumbnail":"https://i.ytimg.com/vi/4kX90HzA0FM/hqdefault.jpg","type":"youtube","operations":[{"name":"download","text":"Download","successMessage":"Video downloaded"}],"format":"high"}

This is the raw JSON data that the server process receives from the web client. If format is not high, that means that's something wrong with the front-end code.

orithena commented 7 years ago

I also checked what youtube-dl does, exactly. From this error message, it seems that youtube-dl is able to work with DASH streams including muxing video and audio together:

WARNING: Your copy of avconv is outdated and unable to properly mux separate video and audio files, youtube-dl will download single file media. Update avconv to version 10-0 or newer to fix this.

But YouTuPi doesn't use youtube-dl to actually download the video, it's just that the library we use (pafy) depends on youtube-dl to fetch the meta data. We simply extract the video URL of the highest quality stream that's playable and run omxplayer <URL>.