[BUGFIX] Fix Windows split by chapters not reading chapter titles correctly (#591)
This commit is contained in:
parent
9a5ee716cf
commit
1588725bb1
3 changed files with 19 additions and 61 deletions
|
|
@ -302,21 +302,24 @@ class ChaptersPlugin(Plugin[ChaptersOptions]):
|
||||||
"""
|
"""
|
||||||
chapters = Chapters.from_empty()
|
chapters = Chapters.from_empty()
|
||||||
|
|
||||||
|
# If there are no embedded chapters, and comment chapters are allowed...
|
||||||
if not _contains_any_chapters(entry) and self.plugin_options.allow_chapters_from_comments:
|
if not _contains_any_chapters(entry) and self.plugin_options.allow_chapters_from_comments:
|
||||||
|
# Try to get chapters from comments
|
||||||
for comment in entry.kwargs_get(COMMENTS, []):
|
for comment in entry.kwargs_get(COMMENTS, []):
|
||||||
chapters = Chapters.from_string(comment.get("text", ""))
|
chapters = Chapters.from_string(comment.get("text", ""))
|
||||||
if not chapters.is_empty():
|
if chapters.contains_any_chapters():
|
||||||
break
|
break
|
||||||
|
|
||||||
if not chapters.is_empty():
|
# If some are actually found, add a special kwarg and embed them
|
||||||
entry.add_kwargs({YTDL_SUB_CUSTOM_CHAPTERS: chapters.to_file_metadata_dict()})
|
if chapters.contains_any_chapters():
|
||||||
|
entry.add_kwargs({YTDL_SUB_CUSTOM_CHAPTERS: chapters.to_file_metadata_dict()})
|
||||||
|
|
||||||
if not self.is_dry_run:
|
if not self.is_dry_run:
|
||||||
set_ffmpeg_metadata_chapters(
|
set_ffmpeg_metadata_chapters(
|
||||||
file_path=entry.get_download_file_path(),
|
file_path=entry.get_download_file_path(),
|
||||||
chapters=chapters,
|
chapters=chapters,
|
||||||
file_duration_sec=entry.kwargs("duration"),
|
file_duration_sec=entry.kwargs("duration"),
|
||||||
)
|
)
|
||||||
|
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,14 +164,7 @@ class SplitByChaptersPlugin(Plugin[SplitByChaptersOptions]):
|
||||||
Tags the entry's audio file using values defined in the metadata options
|
Tags the entry's audio file using values defined in the metadata options
|
||||||
"""
|
"""
|
||||||
split_videos_and_metadata: List[Tuple[Entry, FileMetadata]] = []
|
split_videos_and_metadata: List[Tuple[Entry, FileMetadata]] = []
|
||||||
|
chapters = Chapters.from_entry_chapters(entry=entry)
|
||||||
if self.is_dry_run:
|
|
||||||
chapters = Chapters.from_entry_chapters(entry=entry)
|
|
||||||
else:
|
|
||||||
chapters = Chapters.from_embedded_chapters(
|
|
||||||
ffprobe_path=FFMPEG.ffprobe_path(),
|
|
||||||
file_path=entry.get_download_file_path(),
|
|
||||||
)
|
|
||||||
|
|
||||||
# If no chapters, do not split anything
|
# If no chapters, do not split anything
|
||||||
if not chapters.contains_any_chapters():
|
if not chapters.contains_any_chapters():
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import json
|
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
|
from ytdl_sub.entries.variables.kwargs import CHAPTERS
|
||||||
|
from ytdl_sub.entries.variables.kwargs import YTDL_SUB_CUSTOM_CHAPTERS
|
||||||
from ytdl_sub.utils.file_handler import FileMetadata
|
from ytdl_sub.utils.file_handler import FileMetadata
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -220,45 +220,6 @@ class Chapters:
|
||||||
|
|
||||||
return Chapters(timestamps=timestamps, titles=titles)
|
return Chapters(timestamps=timestamps, titles=titles)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_embedded_chapters(cls, ffprobe_path: str, file_path: str) -> "Chapters":
|
|
||||||
"""
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
ffprobe_path
|
|
||||||
Path to ffprobe executable
|
|
||||||
file_path
|
|
||||||
File to read ffmpeg chapter metadata from
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
Chapters object
|
|
||||||
"""
|
|
||||||
proc = subprocess.run(
|
|
||||||
[
|
|
||||||
ffprobe_path,
|
|
||||||
"-loglevel",
|
|
||||||
"quiet",
|
|
||||||
"-print_format",
|
|
||||||
"json",
|
|
||||||
"-show_chapters",
|
|
||||||
"--",
|
|
||||||
file_path,
|
|
||||||
],
|
|
||||||
check=True,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
|
|
||||||
embedded_chapters = json.loads(proc.stdout)
|
|
||||||
timestamps: List[Timestamp] = []
|
|
||||||
titles: List[str] = []
|
|
||||||
for chapter in embedded_chapters["chapters"]:
|
|
||||||
timestamps.append(Timestamp.from_seconds(int(float(chapter["start_time"]))))
|
|
||||||
titles.append(chapter["tags"]["title"])
|
|
||||||
|
|
||||||
return Chapters(timestamps=timestamps, titles=titles)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_entry_chapters(cls, entry: Entry) -> "Chapters":
|
def from_entry_chapters(cls, entry: Entry) -> "Chapters":
|
||||||
"""
|
"""
|
||||||
|
|
@ -274,9 +235,10 @@ class Chapters:
|
||||||
timestamps: List[Timestamp] = []
|
timestamps: List[Timestamp] = []
|
||||||
titles: List[str] = []
|
titles: List[str] = []
|
||||||
|
|
||||||
chapters = {}
|
# Try to get actual yt-dlp chapters first, then custom chapters, then default to empty list
|
||||||
if entry.kwargs_contains("chapters"):
|
chapters = entry.kwargs_get(
|
||||||
chapters = entry.kwargs("chapters") or []
|
CHAPTERS, default=entry.kwargs_get(YTDL_SUB_CUSTOM_CHAPTERS, default=[])
|
||||||
|
)
|
||||||
|
|
||||||
for chapter in chapters:
|
for chapter in chapters:
|
||||||
timestamps.append(Timestamp.from_seconds(int(float(chapter["start_time"]))))
|
timestamps.append(Timestamp.from_seconds(int(float(chapter["start_time"]))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue