Skip to content

Commit

Permalink
Add separate quality entry for iOS compatibility
Browse files Browse the repository at this point in the history
The iOS-compatible video may not be the best quality. Add a separate quality option to accommodate people who want the best available versus the best compatible with iOS's strict requirements.

Testing with https://www.youtube.com/watch?v=YiRMs5ZhcH4 where the best quality video is 2160p and not iOS-compatible.

With best quality, the VP9 video format is used (better quality but not iOS-compatible):

```
% ffprobe -hide_banner Who\ Can\ Find\ the\ Weirdest\ PC\ Parts\ on\ AliExpress?.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Who Can Find the Weirdest PC Parts on AliExpress?.mp4':
Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2mp41
encoder         : Lavf60.16.100
Duration: 00:19:02.72, start: 0.000000, bitrate: 10941 kb/s
Stream #0:0[0x1](und): Video: vp9 (Profile 0) (vp09 / 0x39307076), yuv420p(tv, bt709), 3840x1920, 10805 kb/s, 29.97 fps, 29.97 tbr, 16k tbn (default)
Metadata:
handler_name    : ISO Media file produced by Google Inc. Created on: 06/15/2024.
vendor_id       : [0][0][0][0]
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name    : ISO Media file produced by Google Inc.
vendor_id       : [0][0][0][0]
```

With "Best (iOS)" quality, the H264 video (lower quality but iOS-compatible) is used:

```
% ffprobe -hide_banner Who\ Can\ Find\ the\ Weirdest\ PC\ Parts\ on\ AliExpress?.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Who Can Find the Weirdest PC Parts on AliExpress?.mp4':
Metadata:
major_brand     : isom
minor_version   : 512
compatible_brands: isomiso2avc1mp41
encoder         : Lavf60.16.100
Duration: 00:19:02.72, start: 0.000000, bitrate: 1846 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x960 [SAR 1:1 DAR 2:1], 1710 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
Metadata:
handler_name    : ISO Media file produced by Google Inc.
vendor_id       : [0][0][0][0]
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name    : ISO Media file produced by Google Inc.
vendor_id       : [0][0][0][0]
```

Included a README note about the new quality option.
  • Loading branch information
jgoguen committed Jun 15, 2024
1 parent 6b4db7c commit 41da9fd
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ __Firefox:__ contributed by [nanocortex](https://github.com/nanocortex). You can

[rithask](https://github.com/rithask) has created an iOS shortcut to send the URL to MeTube from Safari. Initially, you'll need to enter the server address and port, but after that, it will be saved and you can just run the shortcut from the share menu in Safari. The address should include the protocol (http/https) and the port, if it's not the default 80/443. For example: `https://metube.example.com` or `http://192.168.1.1:8081`. The shortcut can be found [here](https://www.icloud.com/shortcuts/f1548df15b734418a77a709103bc1dd5).

## iOS Compatibility

iOS has strict requirements for video files, requiring h264 or h265 video codec and aac audio codec in MP4 container. This can sometimes be a lower quality than the best quality available. To accommodate iOS requirements, when downloading a MP4 format you can choose "Best (iOS)" to get the best quality formats as compatible as possible with iOS requirements.

## Bookmarklet

[kushfest](https://github.com/kushfest) has created a Chrome bookmarklet for sending the currently open webpage to MeTube. Please note that if you're on an HTTPS page, your MeTube instance must be behind an HTTPS reverse proxy (see below) for the bookmarklet to work.
Expand Down
18 changes: 10 additions & 8 deletions app/dl_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@ def get_format(format: str, quality: str) -> str:
return "bestaudio/best"
# video {res} {vfmt} + audio {afmt} {res} {vfmt}
vfmt, afmt = ("[ext=mp4]", "[ext=m4a]") if format == "mp4" else ("", "")
vres = f"[height<={quality}]" if quality != "best" else ""
vres = f"[height<={quality}]" if quality not in ("best", "best_ios") else ""
vcombo = vres + vfmt

# iOS has strict requirements for video files, requiring h264 or h265
# video codec and aac audio codec in MP4 container. This format string
# attempts to get the fully compatible formats first, then the h264/h265
# video codec with any M4A audio codec (because audio is faster to
# convert if needed), and falls back to getting the best available MP4
# file.
return f"bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio[acodec=aac]/bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio{afmt}/bestvideo{vcombo}+bestaudio{afmt}/best{vcombo}"
if quality == "best_ios":
# iOS has strict requirements for video files, requiring h264 or h265
# video codec and aac audio codec in MP4 container. This format string
# attempts to get the fully compatible formats first, then the h264/h265
# video codec with any M4A audio codec (because audio is faster to
# convert if needed), and falls back to getting the best available MP4
# file.
return f"bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio[acodec=aac]/bestvideo[vcodec~='^((he|a)vc|h26[45])']{vres}+bestaudio{afmt}/bestvideo{vcombo}+bestaudio{afmt}/best{vcombo}"
return f"bestvideo{vcombo}+bestaudio{afmt}/best{vcombo}"

raise Exception(f"Unkown format {format}")

Expand Down
17 changes: 5 additions & 12 deletions ui/src/app/formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const Formats: Format[] = [
text: 'MP4',
qualities: [
{ id: 'best', text: 'Best' },
{ id: 'best_ios', text: 'Best (iOS)' },
{ id: '1440', text: '1440p' },
{ id: '1080', text: '1080p' },
{ id: '720', text: '720p' },
Expand Down Expand Up @@ -55,29 +56,21 @@ export const Formats: Format[] = [
{
id: 'opus',
text: 'OPUS',
qualities: [
{ id: 'best', text: 'Best' },
],
qualities: [{ id: 'best', text: 'Best' }],
},
{
id: 'wav',
text: 'WAV',
qualities: [
{ id: 'best', text: 'Best' },
],
qualities: [{ id: 'best', text: 'Best' }],
},
{
id: 'flac',
text: 'FLAC',
qualities: [
{ id: 'best', text: 'Best' },
],
qualities: [{ id: 'best', text: 'Best' }],
},
{
id: 'thumbnail',
text: 'Thumbnail',
qualities: [
{ id: 'best', text: 'Best' }
],
qualities: [{ id: 'best', text: 'Best' }],
},
];

0 comments on commit 41da9fd

Please sign in to comment.