-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate cover [a.k.a. thumbnail/poster] for video manually uploaded #196
Changes from all commits
d81458a
0416359
9ef5a1d
f8c39f2
46f0e6c
2bdd296
3379ee8
3a965f8
90f0b50
cbaad2b
e7d9636
686d6a3
10296a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,9 +20,10 @@ | |
import datetime | ||
import os | ||
import hashlib | ||
import subprocess | ||
# import shlex | ||
import shutil | ||
import sqlite3 | ||
from subprocess import run | ||
from flask_babel import gettext as _ | ||
|
||
from . import logger, comic, isoLanguages | ||
|
@@ -304,6 +305,7 @@ def video_metadata(tmp_file_path, original_file_name, original_file_extension): | |
else: | ||
log.warning('Cannot find the xklb database, using default metadata') | ||
else: | ||
generate_video_cover(tmp_file_path) | ||
meta = BookMeta( | ||
file_path=tmp_file_path, | ||
extension=original_file_extension, | ||
|
@@ -320,22 +322,32 @@ def video_metadata(tmp_file_path, original_file_name, original_file_extension): | |
identifiers=[]) | ||
return meta | ||
|
||
# Yes shlex.quote() can help! But flags/options/switchs can still be dangerous: | ||
# https://stackoverflow.com/questions/49573852/is-python3-shlex-quote-safe | ||
# def sanitize_path(path): | ||
# """Sanitize the file path to prevent command injection.""" | ||
# return shlex.quote(path) | ||
|
||
def generate_video_cover(tmp_file_path): | ||
ffmpeg_executable = os.getenv('FFMPEG_PATH', 'ffmpeg') | ||
ffmpeg_output_file = os.path.splitext(tmp_file_path)[0] + '.cover.jpg' | ||
|
||
ffmpeg_args = [ | ||
ffmpeg_executable, | ||
'-i', tmp_file_path, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defensive programming reminder: Sanitize the file path to prevent command injection There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a general warning that (Though it's probably good enough for path sanitizing!) |
||
'-vframes', '1', | ||
'-y', ffmpeg_output_file | ||
'-vf', 'fps=1,thumbnail,select=gt(scene\,0.1),scale=-1:720', # apply filters to avoid black frames and scale | ||
'-frames:v', '1', # extract only one frame | ||
'-vsync', 'vfr', # variable frame rate | ||
'-y', # overwrite output file if it exists | ||
ffmpeg_output_file | ||
] | ||
|
||
try: | ||
ffmpeg_result = run(ffmpeg_args, capture_output=True, check=True) | ||
ffmpeg_result = subprocess.run(ffmpeg_args, capture_output=True, check=True) | ||
log.debug(f"ffmpeg output: {ffmpeg_result.stdout}") | ||
|
||
except Exception as e: | ||
log.warning(f"ffmpeg failed: {e}") | ||
log.error(f"ffmpeg failed: {e}") | ||
return None | ||
|
||
def image_metadata(tmp_file_path, original_file_name, original_file_extension): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the same video