ytdl-org / youtube-dl

Command-line program to download videos from YouTube.com and other video sites
http://ytdl-org.github.io/youtube-dl/
The Unlicense
132.06k stars 10.02k forks source link

[Feature request] Add a possibility to use ffmpeg (instead of AtomicParsey) to embed thumbnail in downloaded video #24882

Open sebma opened 4 years ago

sebma commented 4 years ago

Checklist

Description

Hi,

Since version 4, ffmpeg is able to embed thumbnail in mp4 files : See https://www.ffmpeg.org/ffmpeg.html#Main-options and : https://stackoverflow.com/q/54717175/5649639

I cannot build/find AtomicParsley for SailfishOS, can you please add the possibility to use ffmpeg (instead of AtomicParsley) to embed thumbnail in downloaded video ?

Thanks a lot to your team for your great amount of work for this great tool I use everyday (along with mpv:-) )

Seirdy commented 4 years ago

This would also be great for embedding thumbnails in container formats besides mp3 and mp4a/mp4 (e.g., Matroska mkv).

sebma commented 4 years ago

Also because AtomicParsley cannot embed old JPEG thumbnails that are not JFIF, such as the ones provided by Dailymotion :

$ curl -qs $(youtube-dl https://www.dailymotion.com/video/x5qpdm --get-thumbnail) | file -b -
JPEG image data
$ curl -qs $(youtube-dl https://www.youtube.com/watch?v=s13q9GhousM --get-thumbnail) | file -b -
JPEG image data, JFIF standard 1.01
$ AtomicParsley Bug2000__hls-380-0__x5qpdm__dailymotion.mp4  --artwork Bug2000__hls-380-0__x5qpdm__dailymotion.jpg --overWrite
AtomicParsley error: Bug2000__hls-380-0__x5qpdm__dailymotion.jpg
     image file is not jpg/png and cannot be embedded.
$ convert -verbose Bug2000__hls-380-0__x5qpdm__dailymotion.jpg Bug2000__hls-380-0__x5qpdm__dailymotion__NEW.jpg
Bug2000__http-380-1__x5qpdm__dailymotion.jpg JPEG 1440x1080 1440x1080+0+0 8-bit DirectClass 81.3KB 0.040u 0:00.050
Bug2000__http-380-1__x5qpdm__dailymotion.jpg=>Bug2000__hls-380-0__x5qpdm__dailymotion__NEW.jpg JPEG 1440x1080 1440x1080+0+0 8-bit DirectClass 81.9KB 0.060u 0:00.059
$ file Bug2000__hls-380-0__x5qpdm__dailymotion.jpg Bug2000__hls-380-0__x5qpdm__dailymotion__NEW.jpg
Bug2000__hls-380-0__x5qpdm__dailymotion.jpg:      JPEG image data
Bug2000__hls-380-0__x5qpdm__dailymotion__NEW.jpg: JPEG image data, JFIF standard 1.01
$ AtomicParsley Bug2000__hls-380-0__x5qpdm__dailymotion.mp4  --artwork Bug2000__hls-380-0__x5qpdm__dailymotion__NEW.jpg --overWrite

 Started writing to temp file.
 Progress: =======================================================>100% |
 Finished writing to temp file.
sebma commented 4 years ago

BTW : The AtomicParsley issue #48 has been reported since December 2016.

Vangelis66 commented 4 years ago

@sebma : You do have a valid argument here πŸ‘ , but FFmpeg 4.x.x branches require Windows Vista or higher to run; and that min WinOS requirement is for vanilla FFmpeg code; some third-party libs (e.g. libx265), when compiled with default configuration, require themselves additionally Win7 as a bare minimum WinOS (and this is precisely the reason the Zeranoe FFmpeg binaries won't run under Vista 😞 ) - OTOH, AP Windows binaries run on WinXP+...

The Windows binary of yt-dl, youtube-dl.exe , is being compiled with Python 3.4.4, which is the last WinXP compatible version; so I assume the devs have some vested interest in still supporting WinXP and, though on Vista myself in my older laptop, I do applaud that support πŸ‘ ...

BTW, FFmpeg 4.x.x can also embed artwork as cover to .m4a audio files, not only to A+V .mp4 ones:

ffmpeg -v 16 -stats -i "audio-only.m4a" -i "cover.jpg" -map 0 -map 1 -disposition:v attached_pic -c copy "audio+cover.m4a"

... so I'd say it could probably replace fully AP for MOV/MP4/M4A tagging/artwork-embedding; and since yt-dl already depends on FFmpeg (for muxing elementary media streams into compatible containers and for cases where the native HLS downloader fails), one can kill two birds with one stone, by getting rid of AP altogether...

... However, the most wise move would be to retain AP support as an option, for those users that can't run the latest FFmpeg 4 Windows binaries (XP+Vista); I haven't checked, but what is the usage share of SailfishOS compared to the combined figure for XP+Vista?

FWIW, a kind person I know does compile and offer FFmpeg n4.3-dev Windows builds from forked FFmpeg code patched to make them run on XP SP3 (and SSE+ CPUs), but let's cross that bridge when we find it...

The AtomicParsley issue #48 has been reported since December 2016.

If wez has left the AP project to rot away, either you or Logan Fleur can always fork the project and implement needed patches, can you not? Then the yt-dl community here would need a volunteer to compile the forked AP code for at least Windows x86 (targetting XP+)...

effleurager commented 4 years ago

@Vangelis66 I can fork & patch the GitHub project, but not compile it for Windows. I'll do that later tonight when I'm done with work.

Vangelis66 commented 4 years ago

@effleurager wrote:

I can fork & patch the GitHub project

(Do you actually mean the Bitbucket original one by Wez, that uses mercurial version control?) Highly appreciated, many thanks in advance! πŸ‘

but not compile it for Windows

... such a pity, though... For anyone else that may volunteer, (cross)compilation instructions for Windows 32-bit are described/linked in

https://bitbucket.org/jonhedgerows/atomicparsley/wiki/Building%20for%20Windows

Best wishes πŸ˜„

effleurager commented 4 years ago

@Vangelis66 The GitHub one is severely outdated compared to the Mercurial one, so I've used Bitbucket as the source instead. effleurager/atomicparsley now has the patched version.

sebma commented 4 years ago

@Vangelis66

... However, the most wise move would be to retain AP support as an option, for those users that can't run the latest FFmpeg 4 Windows binaries (XP+Vista)

According to https://ffmpeg.zeranoe.com/builds/ : ffmpeg can run on Win7. If it does run on Win7, can it not run on Vista ?

If wez has left the AP project to rot away, either you or Logan Fleur can always fork the project and implement needed patches, can you not?

Unfortunately, I'm a better "scripter" than developer : I don't know anything about cross-compiling except doing somethig like this (to build AP for SailfishOS) :

dest=arm-linux-gnueabihf
export CC=$dest-gcc
time ./configure --prefix=$HOME/build/jolla --host=$dest
time make

If I knew more, I would have succeeded building AP on SailfishOS.

I haven't checked, but what is the usage share of SailfishOS compared to the combined figure for XP+Vista?

You're absolutely right :+1:, but I've been dreaming for a real Linux smartphone for so long :smiley: Nevertheless, I never suggested to abandon AtomicParsley, I do understand the need for AtomicParsley on WinXP+.

However, can we also consider the possiblity to have a new youtube-dl option to use ffmpeg as an alternative tool for youtube-dl to embed thumbnails on Linux platforms, for exemple :

       --external-thumbnailer COMMAND
              Use the specified external thumbnailer.  Currently supports AtomicParsley,ffmpeg
sebma commented 4 years ago

@Vangelis66

BTW, FFmpeg 4.x.x can also embed artwork as cover to .m4a audio files, not only to A+V .mp4 ones:

ffmpeg -v 16 -stats -i "audio-only.m4a" -i "cover.jpg" -map 0 -map 1 -disposition:v attached_pic -c copy "audio+cover.m4a"

:+1:

I also noticed ffmpeg CAN embed subtitles into m4a files (so that song lyrics are displayed over the thumbnail when the file is played with mpv) :

addSubtitles2media ()
{
    local inputVideo=$1
    test $# -le 1 && {
        echo "=> Usage: $FUNCNAME inputVideo subFile1 subFile2 subFile3 ..." 1>&2
        return 1
    }
    local extension=${inputVideo/*./}
    case $extension in
        mp4 | m4a | m4b | mov)
            subTitleCodec=mov_text
        ;;
        webm | mkv | mka)
            subTitleCodec=webvtt
        ;;
        *)
            subTitleCodec=not_known_or_not_yet_supported
        ;;
    esac
    local outputVideo=${inputVideo/.$extension/_NEW.$extension}
    shift
    local numberOfSubtitles=$#
    ( printf "ffmpeg -hide_banner -i $inputVideo "
    printf -- "-i %s " "$@"
    printf -- "-map 0:a? -map 0:v? "
    printf -- "-map %d " $(seq $numberOfSubtitles)
    printf -- "-c copy -c:s $subTitleCodec $outputVideo\n" ) | sh -x
    local retCode=$?
    sync
    sleep 1
    touch -r "$inputVideo" "$outputVideo"
    [ $retCode = 0 ] && echo && \mv -vf "$outputVideo" "$inputVideo" && \rm "$@"
}

I haven't tried it on Matroska contained streams but I can say it works like a charm on m4a files :smile: :

ffprobe -hide_banner Alan_Jackson_-_I_Want_To_Stroll_Over_Heaven_With_You_Live__140__UnZbjvyzteo__youtube_com.m4a
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5655577e84c0] stream 0, timescale not set
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Alan_Jackson_-_I_Want_To_Stroll_Over_Heaven_With_You_Live__140__UnZbjvyzteo__youtube_com.m4a':
  Metadata:
    major_brand     : M4A 
    minor_version   : 512
    compatible_brands: isomiso2
    title           : Alan Jackson - I Want To Stroll Over Heaven With You (Live)
    artist          : GaitherVEVO
    date            : 20170824
    encoder         : Lavf58.20.100
    comment         : Alan Jackson – Official Video for β€œI Want To Stroll Over Heaven With You Live”, available now!
                    : 
                    : Buy the full-length DVD/CD β€˜Alan Jackson Precious Memories: Live at the Ryman Auditorium' Here: http://capcmg.me/preciousmemories
                    : Available at Amazon: http://capcmg.me/am.preciousmemories
                    : 
                    : Sign-Up for the Gaither Newsletter and receive $5 off your next online purchase: http://smarturl.it/GaitherNewsletter
                    : 
                    : Subscribe to Gaither Music YouTube Channel: http://smarturl.it/GaitherMusicTV_Subsc
                    : Subscribe to GaitherVEVO Channel: http://smarturl.it/GaitherVEVOSubscribe
                    : Subscribe to Gaither TV: http://smarturl.it/GaitherTV_Subscribe
                    : 
                    : Follow Gaither Music for updates on your favorite artists.
                    : Facebook: http://smarturl.it/FB_GaitherMusic
                    : Twitter: http://smarturl.it/TW_GaitherMusic
                    : Instagram: http://smarturl.it/IG_GaitherMusic
                    : Website: http://smarturl.it/gaither.com
                    : 
                    : LYRICS:
                    : 
                    : If I survey all the good things that come to me from above
                    : If I count all the blessings from the storehouse of love
                    : I'd simply ask for the favor of him beyond mortal king
                    : And I'm sure he would grant it again
                    : I want to stroll over Heaven with you some glad day
                    : When all our troubles and heartaches are vanished away
                    : Then we'll enjoy the beauty where all things are new
                    : I want to stroll over Heaven with you
                    : 
                    : So many places of beauty we long to see here below
                    : But time and treasures have kept us from making plans as you know
                    : But come the morning of rapture together we'll stand a new
                    : While I stroll over Heaven with you
                    : I want to stroll over Heaven with you some glad day
                    : When all our troubles and heartaches are vanished away
                    : Then we'll enjoy the beauty where all things are new
                    : I want to stroll over Heaven with you
                    : 
                    : Music video by Alan Jackson performing I Want To Stroll Over Heaven With You. (C) 2017 ACR Records, LLC Under license to Spring House Productions, Inc.
                    : 
                    : http://vevo.ly/gumdxW
    description     : https://www.youtube.com/watch?v=UnZbjvyzteo
  Duration: 00:02:52.80, start: 0.000000, bitrate: 133 kb/s
    Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      handler_name    : ISO Media file produced by Google Inc.
    Stream #0:1(und): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
    Metadata:
      handler_name    : SubtitleHandler
    Stream #0:2(und): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s
    Metadata:
      handler_name    : SubtitleHandler
    Stream #0:3(und): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s
    Metadata:
      handler_name    : SubtitleHandler
    Stream #0:4(und): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s
    Metadata:
      handler_name    : SubtitleHandler
    Stream #0:5: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 90k tbr, 90k tbn, 90k tbc
sebma commented 3 years ago

Hi,

Also because AtomicParsley cannot embed old JPEG thumbnails that are not JFIF, such as the ones provided by Dailymotion :

For information :

The AtomicParsley project has moved to GitHub : https://github.com/wez/atomicparsley

and the gitlab bug # 48 (AtomicParsley cannot embed old JPEG thumbnails that are not JFIF) has been fixed in commit f927648 since Jul 1, 2020.

Vangelis66 commented 3 years ago

and bug #48 (AtomicParsley cannot embed old JPEG thumbnails that are not JFIF)

Most sadly, old bitbucket bug #48 is no longer accessible (it 404s); GitHub auto-redirects to a completely different yt-dl issue no. 48 😠 ...

EDIT: Salvaged in the web archive πŸ‘ :

http://web.archive.org/web/20200723103234/https://bitbucket.org/wez/atomicparsley/issues/48/

has been fixed in commit f927648

... But the fix is NOT available to 32-bit Windows users, because wez is unwilling to provide a 32-bit AP binary 😞 ; so, while I can use official youtube-dl.exe (which, thankfully πŸ‘ , is still 32-bit), I can't use (or compile myself 😒 ) the AP you mentioned, with the Dailymotion fix... πŸ‘Ž

FWIW, I had filed https://github.com/wez/atomicparsley/issues/6 more than a year ago, but, most sadly, it hasn't seen any activity since then... 😿

If anyone can help compile wez's AP in a 32-bit flavour, please come forth (preferably with a PR in the original repo, so that future AP updates are also released in x86...).

sebma commented 3 years ago

@Vangelis66 I have just received this comment from the github-action bot after creating a tiny issue today on AP (AtomicParsley, right ? :smile: ) :

Thanks for filing an issue! Please note that this project is only passively maintained, so your best bet for getting an issue resolved is through a pull request that is easy to verify! Please read this for more information.

Unless, someone knows how to create a PR for that need (which btw wez agrees merging if they are easy to read), all you can do is :pray:

sebma commented 3 years ago

And although the JFIF fix has been commited since Jul 1, 2020, unfortunately for Debian and Ubuntu users this AP release is still not available in the latest distribution Debian/Ubuntu release repositories : see https://packages.debian.org/sid/atomicparsley and https://packages.ubuntu.com/search?keywords=atomicparsley

wez commented 3 years ago

Folks, it feels like there's a lot of negative sentiment directed towards me in this issue.

wez is unwilling to provide a 32-bit AP binary

unwilling is a strong word. I simply don't have time for it, and I get literally nothing out of maintaining this project that I don't use.

If you submit PRs to add what you need then you can make these things happen!

effleurager commented 3 years ago

unfortunately for Debian and Ubuntu users this AP release is still not available in the latest distribution Debian/Ubuntu release repositories

@sebma You can always ask a question via launchpad, letting them know their update process is no longer working.

sebma commented 3 years ago

@effleurager On launchpad.net, I only know how to report a bug.

Besides, I'm not sure this is about their automatic update process because it seems they're using a very old atomicparsley package as it refers to http://atomicparsley.sourceforge.net/ instead of https://github.com/wez/atomicparsley :

$ apt-cache show atomicparsley | grep Homepage:
Homepage: http://atomicparsley.sourceforge.net/
sebma commented 3 years ago

@Vangelis66 Although wez does not get paid for working on AP, he did a great job helping me creating my very first PR on github : https://github.com/wez/atomicparsley/issues/34#issuecomment-881051716

If you know your way around the [CMakeLists.txt] file (cmake doc here), maybe you can edit it on github : https://github.com/wez/atomicparsley/issues/34#issuecomment-881010404

and find finally create your own PR (graphically with github) to help build AtomicParsley for XP 32bits environment.

Just one more thing : I speak on behalf of pure users and I include myself, I believe us users must be nicer with the developers because we have no idea how much of their personal life they sacrifice to make computers and programs easier to use for everyone and those on GitHub/GitLab/Bitbucket/etc... do it for FREE !

Let us be more grateful.

@wez Thanks again for your help.

Emasoft commented 1 year ago

@ghost pull request finally solves this issue. Why is not merged?

Vangelis66 commented 1 year ago

@Emasoft :

youtube-dl, unlike the downstream fork, still caters to older python versions (2.6-2.7, 3.2-3.9+), to be found on older distros or still compatible with Win<=7... Those "older" setups/environments don't always come with (or can be upgraded to) FFmpeg branch 4.x.x, the minimum required for MP4-container tagging via FFmpeg, and I suspect that's the main reason #29593 (NB, has #29581 as a prerequisite!) hasn't been merged to this day...

I didn't bother to dissect the code involved 😊 , but if the PR's "logic" can fall-back to an existing AtomicParsley binary (for MP4-tagging) when installed FFmpeg doesn't meet the minimum requirements, then I suppose it could still find its way towards the master youtube-dl branch 😜 ... But that's up to current (sole) maintainer to decide πŸ˜„ ...

pukkandan commented 1 year ago

yt-dlp tries first with mutagen, then atomicparsley and ffmpeg only as a last resort. The reason is that thumbnails embedded with ffmpeg does not appear as cover in some programs

Emasoft commented 1 year ago

Ffmpeg embeds covers very well. It works better than Mutagen in my experience (some thumbs are not shown with mutagen embedded covers, while they are perfectly shown with ffmpeg embedded covers). But you need to fine tune the ffmpeg parameters to get maximum compatibility for many players and OSs. (It is also best practice to rename m4a and m4b extensions to .mp4, to maximize compatibility. Some OSs do not even check files with m4a or m4b extensions for thumbnails.)

This is my fine tuned and tested command for embedding jpg covers in m4a, mp4, mov and m4b audio files (note: the placeholders in curly brackets must be replaced by the real value. For png covers you need to replace -c:v:1 mjpeg with -c:v:1 png):

$> ffmpeg -y -i "{audiofilename}" -i "{imagefilename}" -map 0:a -map 1:v -c:a copy -c:v:1 mjpeg -id3v2_version 3 -write_id3v1 1 -metadata:s:v "title=Album cover" -metadata:s:v "comment=Cover (front)" -disposition:v:1 attached_pic "{audiofilename_noextension}_withcover.{extension}"

This is my fine tuned and tested command for embedding covers in mp3 audio files (note: the placeholders in curly brackets must be replaced by the real value):

$> ffmpeg -y -i "{imagefilename}" -i "{audiofilename}" -c:a copy -c:v copy -map 0:v -map 1:a -id3v2_version 3 -write_id3v1 1 -map_metadata 0:g -map_metadata 1:g -metadata:s:v 'title="Album cover"' -metadata:s:v 'comment="Cover (front)"' -disposition:v:0 attached_pic "{audiofilename_noextension}_withcover.{extension}"

Notice the subtle differences between the two? All details are necessary to make it works, from the order of arguments to the different nesting of apostrophes and commas. Of curse in python you need to escape some quotes with backslash.

To convert the webp images to jpg I use this ffmpeg command (note: the placeholders in curly brackets must be replaced by the real value):

$> ffmpeg -y -i "{imagefilename_webp}" -bsf:v mjpeg2jpeg "{imagefilename_jpg}"

Works fine every time.

nicolaasjan commented 1 year ago

To convert the webp images to jpg I use this ffmpeg command (note: the placeholders in curly brackets must be replaced by the real value):

$> ffmpeg -y -i "{imagefilename_webp}" -bsf:v mjpeg2jpeg "{imagefilename_jpg}"

Works fine every time.

Slightly offtopic, but I always add -qmin 1 -q:v 1 to that, to have the best possible jpeg quality. See stackoverflow.

My script:

#!/bin/bash
for i in *.webp; do ffmpeg -i "${i}" -qmin 1 -q:v 1 -bsf:v mjpeg2jpeg "${i%.webp}.jpg"; done

Tested with the .webp from this video it is 46,8Β kB vs 140,2Β kB. When zooming in, you can clearly see more compression artefacts in the first one.