home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
72.25k stars 30.24k forks source link

FFMPEG integration "drawtext filter" not working (overlay text on image/video) #41749

Closed OkhammahkO closed 3 years ago

OkhammahkO commented 3 years ago

The problem

I want to use the FFMPEG integration, the FFMPEG drawtext filter, and a shell command to read a local image (from www), overlay text on it (timestamp), and write it back to www.

https://ffmpeg.org/ffmpeg-filters.html#drawtext-1

I think this is what FFMPEG uses to draw (for example) timestamp overlays on a camera stream?

I've tried so many syntax variants that at this point I suspect it is either:

  1. Configuration of the FFMPEG integration (--enable-libfreetype, --enable-libfontconfig) ~ see drawtext help above.
  2. Something to do with where font files (.ttf or .woff?) need to be with a hassio integration (tried many variants of www locations)
  3. Some other bug....

My drawtext test commands were working when tested on a Windows FFMPEG installation. I can read/write the image just fine in hassio (can copy/paste/rename file in www via shell command etc )

I also tried testing the filter as an 'extra_arguments' on a FFMPEG camera, but couldn't get that to work either.

This guy was having some problem with drawtext too: https://community.home-assistant.io/t/camera-with-rtmp-stream/141594 And here's my plea for help: https://community.home-assistant.io/t/how-to-draw-text-on-image-ffmpeg-drawtext-command/230963

I would love to have a timestamp overlay on my fancy thing (use case): https://www.linkedin.com/posts/mahko-blackburn-00605171_iso-project-i-analysed-my-view-of-port-melbourne-ugcPost-6720535284552994816-sv3R

Environment

docker true
docker_version 19.03.11
hassio true
host_os HassOS 4.13
installation_type Home Assistant OS
os_name Linux
os_version 4.19.127-v7l
python_version 3.8.5
supervisor 247
version 0.116.2

Problem-relevant configuration.yaml

In config: ffmpeg:

I feel like I've tried a silly number of variants of commands that both do and don't appear below. Having feeling i've exhausted syntax variants, I'm raising it as a possible integration issue

I've also reviewed various community threads like this and asked the community for help

shell_command:
 drawtext: 'ffmpeg -i /config/www/motioneye_files/GiraffeCam1/all_timelapse/lastestGiraffe.jpg -vf drawtext=fontfile="arial.ttf":text=Last60min -y /config/www/motioneye_files/GiraffeCam1/all_timelapse/drawtext_lastestGiraffe.jpg'
 drawtext2: 'ffmpeg -i /config/www/motioneye_files/GiraffeCam1/all_timelapse/lastestGiraffe.jpg -vf drawtext=fontfile=arial.ttf:text=Last60min -y /config/www/motioneye_files/GiraffeCam1/all_timelapse/drawtext_lastestGiraffe.jpg'
 drawtext3: 'ffmpeg -i /config/www/motioneye_files/GiraffeCam1/all_timelapse/lastestGiraffe.jpg -vf drawtext=text=Last60min -y /config/www/motioneye_files/GiraffeCam1/all_timelapse/drawtext_lastestGiraffe.jpg'

Traceback/Error logs

It's pretty silent....

Additional information

probot-home-assistant[bot] commented 3 years ago

ffmpeg documentation ffmpeg source (message by IssueLinks)

KevinCathcart commented 3 years ago

The output of your command is:

[AVFilterGraph @ 0xb48bcf30] No such filter: 'drawtext'
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
Conversion failed!

Looking at the configuration used:

configuration: --prefix=/usr --enable-avresample --enable-avfilter --enable-gnutls --enable-gpl --enable-libass --enable-libmp3lame --enable-libvorbis --enable-libvpx --enable-libxvid --enable-libx264 --enable-libx265 --enable-libtheora --enable-libv4l2 --enable-libdav1d --enable-postproc --enable-pic --enable-pthreads --enable-shared --enable-libxcb --enable-libssh --disable-stripping --disable-static --disable-librtmp --enable-vaapi --enable-vdpau --enable-libopus --disable-debug

It does look like the needed compilation options for ffmpeg are not included.

This is not really related to the ffmpeg integration, but to what is installed in the docker image. The docker image is using the standard alpine linux build of ffmpeg, which does not enable those configuration options.

OkhammahkO commented 3 years ago

Ok, thank you for helping to clarify my issue, it was well over my head. Any suggestions on where to from here? Should I raise a feature request? Or should I just accept that this is not possible? Any other ideas? Thank you!

KevinCathcart commented 3 years ago

Yeah, not really sure myself. My guess is that the Home Assistant core devs would not be enthusiastic about compiling a custom ffmpeg for base container. I cannot swear they would say no, but I would certainly imagine some reluctance.

You could try opening a feature request for the alpine linux ffmpeg package at their GitLab Instance. I literally could not venture a guess as to how they would react. They might be willing to add it, or might not. If not, I'd guess their concern would be bloat (i.e. making the ffmpeg package bigger, and requiring more dependencies).

For alternatives, I'm not really sure. Since we are talking about single images instead of streams: at the very least the Home Assistant Container does contain the pillow fork of the Python Imaging Library, which means that it should be possible to use a python script stored in the config folder and invoked via command_line to draw text on an image. That would be something like a ten line script or so.

Something like:

from PIL import Image, ImageDraw, ImageFont
base = Image.open(sys.argv[1])
fnt = ImageFont.truetype("/config/myfont.ttf", 40) #probably need to adjust the font size, and path to the font
d = ImageDraw.Draw(out)
d.text((10,10), sys.argv[3], font=fnt, fill=(255,255,255)) #probably want to adjust 10,10 to adjust positioning of text
im1.save(sys.argv[2])

If you put the above in a file called "addtext.py" in the config folder, then you could invoke it with the following command line:

shell_command:
   drawtext: python /config/addtext.py /config/www/whatever/inputImage.jpg /config/www/whatever/outputImage.jpg "Text to add to image"

Note: I've not actually tested the above script, but something rather similar to that seems likely to work.

OkhammahkO commented 3 years ago

Much appreciated - thanks for your time. I'll take a look. Whilst I am trying to achieve something different, I would have thought that FFMPEG camera users would like to be able to overlay a timestamp on their FFMPEG cameras (which I understand is not currently possible) , so perhaps it might get traction on that account. Cheers.

OkhammahkO commented 3 years ago

I investigated using Python similar to the above using PILs via Pyscript, but it look like my PIL's is also compiled without the necessary libraries (libfreetype). Resolving this got too hard for me on my Hassio/HassOS system, so I revisited overlaying text within the Home Assisstant motioneye addon I'm using for image capture and this is an acceptable solution/workaround for my use case (you can postion text_left & text_right with spaces and new lines. Can't believe text overlay on a camera stream or image is so hard out of the box....

github-actions[bot] commented 3 years ago

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest Home Assistant version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.