[BUGFIX] Cross-device patch for ffmpeg file writes (#407)
This commit is contained in:
parent
c3d9d45c18
commit
c84496910f
2 changed files with 34 additions and 9 deletions
|
|
@ -32,6 +32,25 @@ class FFMPEG:
|
||||||
"Trying to use a feature which requires ffmpeg, but it cannot be found"
|
"Trying to use a feature which requires ffmpeg, but it cannot be found"
|
||||||
) from subprocess_error
|
) from subprocess_error
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tmp_file_path(cls, relative_file_path: str, extension: Optional[str] = None) -> str:
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
relative_file_path
|
||||||
|
Path of input file that is going to be modified
|
||||||
|
extension
|
||||||
|
Desired output extension. Defaults to input file's extension
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Temporary file path for ffmpeg output
|
||||||
|
"""
|
||||||
|
if extension is None:
|
||||||
|
extension = relative_file_path.split(".")[-1]
|
||||||
|
|
||||||
|
return f"{relative_file_path}.out.{extension}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, ffmpeg_args: List[str]) -> None:
|
def run(cls, ffmpeg_args: List[str]) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
@ -110,8 +129,7 @@ def set_ffmpeg_metadata_chapters(
|
||||||
if chapters:
|
if chapters:
|
||||||
lines += _create_metadata_chapters(chapters=chapters, file_duration_sec=file_duration_sec)
|
lines += _create_metadata_chapters(chapters=chapters, file_duration_sec=file_duration_sec)
|
||||||
|
|
||||||
file_path_ext = file_path.split(".")[-1]
|
tmp_file_path = FFMPEG.tmp_file_path(relative_file_path=file_path)
|
||||||
output_file_path = f"{file_path}.out.{file_path_ext}"
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", encoding="utf-8") as metadata_file:
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", encoding="utf-8") as metadata_file:
|
||||||
metadata_file.write("\n".join(lines))
|
metadata_file.write("\n".join(lines))
|
||||||
metadata_file.flush()
|
metadata_file.flush()
|
||||||
|
|
@ -129,10 +147,10 @@ def set_ffmpeg_metadata_chapters(
|
||||||
"-bitexact", # for reproducibility
|
"-bitexact", # for reproducibility
|
||||||
"-codec",
|
"-codec",
|
||||||
"copy",
|
"copy",
|
||||||
output_file_path,
|
tmp_file_path,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
FileHandler.move(output_file_path, file_path)
|
FileHandler.move(tmp_file_path, file_path)
|
||||||
|
|
||||||
|
|
||||||
def add_ffmpeg_metadata_key_values(file_path: str, key_values: Dict[str, str]) -> None:
|
def add_ffmpeg_metadata_key_values(file_path: str, key_values: Dict[str, str]) -> None:
|
||||||
|
|
@ -144,13 +162,12 @@ def add_ffmpeg_metadata_key_values(file_path: str, key_values: Dict[str, str]) -
|
||||||
key_values
|
key_values
|
||||||
The key/values to add
|
The key/values to add
|
||||||
"""
|
"""
|
||||||
file_path_ext = file_path.split(".")[-1]
|
tmp_file_path = FFMPEG.tmp_file_path(file_path)
|
||||||
output_file_path = f"{file_path}.out.{file_path_ext}"
|
|
||||||
|
|
||||||
ffmpeg_args = ["-i", file_path, "-map", "0"]
|
ffmpeg_args = ["-i", file_path, "-map", "0"]
|
||||||
for key, value in key_values.items():
|
for key, value in key_values.items():
|
||||||
ffmpeg_args.extend(["-metadata", f"{key}={value}"])
|
ffmpeg_args.extend(["-metadata", f"{key}={value}"])
|
||||||
ffmpeg_args.extend(["-codec", "copy", output_file_path])
|
ffmpeg_args.extend(["-codec", "copy", tmp_file_path])
|
||||||
|
|
||||||
FFMPEG.run(ffmpeg_args)
|
FFMPEG.run(ffmpeg_args)
|
||||||
FileHandler.move(output_file_path, file_path)
|
FileHandler.move(tmp_file_path, file_path)
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,14 @@ def convert_url_thumbnail(thumbnail_url: str, output_thumbnail_path: str) -> Opt
|
||||||
thumbnail.write(file.read())
|
thumbnail.write(file.read())
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True)
|
os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True)
|
||||||
FFMPEG.run(["-bitexact", "-i", thumbnail.name, output_thumbnail_path])
|
|
||||||
|
tmp_output_path = FFMPEG.tmp_file_path(
|
||||||
|
relative_file_path=thumbnail.name, extension="jpg"
|
||||||
|
)
|
||||||
|
FFMPEG.run(["-bitexact", "-i", thumbnail.name, tmp_output_path])
|
||||||
|
|
||||||
|
# Have FileHandler handle the move to a potential cross-device
|
||||||
|
FileHandler.move(tmp_output_path, output_thumbnail_path)
|
||||||
|
FileHandler.delete(tmp_output_path)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue