fix (core): main fixes of codec/container/file_extension inconsistency #11
@@ -1,3 +1,3 @@
|
|||||||
"""API route handlers."""
|
"""API route handlers."""
|
||||||
|
|
||||||
from . import upload, split, split_file, status, download, formats, info
|
from . import upload, split, split_file, status, download, websocket, formats, info
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Split task endpoint."""
|
"""Split task endpoint (JSON tracklist)."""
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, BackgroundTasks
|
from fastapi import APIRouter, HTTPException, BackgroundTasks
|
||||||
|
|
||||||
@@ -24,6 +24,29 @@ async def start_split(request: SplitRequest, background_tasks: BackgroundTasks):
|
|||||||
detail=f"Task {task_id} is already {status['status']}"
|
detail=f"Task {task_id} is already {status['status']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Build options dict from request
|
||||||
|
options = {
|
||||||
|
"container": request.container,
|
||||||
|
"audio_codec": request.audio_codec,
|
||||||
|
"video_codec": request.video_codec,
|
||||||
|
"subtitle_codec": request.subtitle_codec,
|
||||||
|
"video_quality": request.video_quality,
|
||||||
|
"drop_video": request.drop_video,
|
||||||
|
"drop_subs": request.drop_subs,
|
||||||
|
"number_tracks": request.number_tracks,
|
||||||
|
"replace_bad_chars": request.replace_bad_chars,
|
||||||
|
"replacement_char": request.replacement_char,
|
||||||
|
"bad_chars": request.bad_chars,
|
||||||
|
"skip_existing": request.skip_existing,
|
||||||
|
"output_template": request.output_template,
|
||||||
|
"album": request.album,
|
||||||
|
"comment": request.comment,
|
||||||
|
"no_comment": request.no_comment,
|
||||||
|
"comment_stream": request.comment_stream,
|
||||||
|
"merge_comments": request.merge_comments,
|
||||||
|
"comment_separator": request.comment_separator,
|
||||||
|
}
|
||||||
|
|
||||||
task_manager.update_task(
|
task_manager.update_task(
|
||||||
task_id,
|
task_id,
|
||||||
status=TaskStatus.PROCESSING,
|
status=TaskStatus.PROCESSING,
|
||||||
@@ -31,9 +54,14 @@ async def start_split(request: SplitRequest, background_tasks: BackgroundTasks):
|
|||||||
message="Preparing to split..."
|
message="Preparing to split..."
|
||||||
)
|
)
|
||||||
|
|
||||||
background_tasks.add_task(run_split_task, task_id, request.tracklist, request.options)
|
background_tasks.add_task(
|
||||||
|
run_split_task,
|
||||||
|
task_id,
|
||||||
|
request.tracklist,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
|
||||||
return SplitResponse(
|
return SplitResponse(
|
||||||
task_id=task_id,
|
task_id=task_id,
|
||||||
status=TaskStatus.PROCESSING
|
status=TaskStatus.PROCESSING
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from fastapi import APIRouter, UploadFile, File, Form, HTTPException, BackgroundTasks
|
from fastapi import APIRouter, UploadFile, File, Form, HTTPException, BackgroundTasks
|
||||||
|
|
||||||
@@ -13,7 +14,6 @@ from backend.models.response import SplitResponse, TaskStatus
|
|||||||
|
|
||||||
router = APIRouter(prefix="/api", tags=["split"])
|
router = APIRouter(prefix="/api", tags=["split"])
|
||||||
|
|
||||||
# Import CLI tracklist parsing functions
|
|
||||||
from audio_splitter.tracklist import parse_format, read_tracklist
|
from audio_splitter.tracklist import parse_format, read_tracklist
|
||||||
|
|
||||||
|
|
||||||
@@ -22,29 +22,33 @@ async def split_from_file(
|
|||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
task_id: str = Form(...),
|
task_id: str = Form(...),
|
||||||
tracklist_file: UploadFile = File(...),
|
tracklist_file: UploadFile = File(...),
|
||||||
options: str = Form("{}"),
|
# New fields
|
||||||
|
container: Optional[str] = Form(None),
|
||||||
|
audio_codec: str = Form("copy"),
|
||||||
|
video_codec: str = Form("copy"),
|
||||||
|
subtitle_codec: str = Form("copy"),
|
||||||
|
video_quality: Optional[int] = Form(None),
|
||||||
|
drop_video: bool = Form(False),
|
||||||
|
drop_subs: bool = Form(False),
|
||||||
|
number_tracks: bool = Form(False),
|
||||||
|
replace_bad_chars: bool = Form(False),
|
||||||
|
replacement_char: str = Form("_"),
|
||||||
|
bad_chars: str = Form(r'!@#№$;:%^&?*(){}[]\/<>+=~`\' '),
|
||||||
|
skip_existing: bool = Form(False),
|
||||||
|
output_template: str = Form("%an-%tn.%ext"),
|
||||||
|
album: Optional[str] = Form(None),
|
||||||
|
comment: Optional[str] = Form(None),
|
||||||
|
no_comment: bool = Form(False),
|
||||||
|
comment_stream: Optional[int] = Form(None),
|
||||||
|
merge_comments: bool = Form(False),
|
||||||
|
comment_separator: str = Form("; "),
|
||||||
|
options: str = Form("{}"), # backward-compatible, but we now use explicit fields
|
||||||
tracklist_format: str = Form("%ts %tn - %an"),
|
tracklist_format: str = Form("%ts %tn - %an"),
|
||||||
):
|
):
|
||||||
"""
|
|
||||||
Start a splitting task using a tracklist file.
|
|
||||||
|
|
||||||
This endpoint accepts a plain text tracklist file (like the CLI does)
|
|
||||||
and parses it using the same logic.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
task_id: Task ID from upload.
|
|
||||||
tracklist_file: Tracklist file (text/plain).
|
|
||||||
options: JSON string of all CLI options.
|
|
||||||
tracklist_format: Format string for parsing (default: "%ts %tn - %an").
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
SplitResponse with task_id and status.
|
|
||||||
"""
|
|
||||||
# Validate task exists
|
# Validate task exists
|
||||||
if not task_manager.has_task(task_id):
|
if not task_manager.has_task(task_id):
|
||||||
raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
|
raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
|
||||||
|
|
||||||
# Check if task is already processing
|
|
||||||
status = task_manager.get_status(task_id)
|
status = task_manager.get_status(task_id)
|
||||||
if status and status["status"] in (TaskStatus.PROCESSING, TaskStatus.DONE):
|
if status and status["status"] in (TaskStatus.PROCESSING, TaskStatus.DONE):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -52,14 +56,12 @@ async def split_from_file(
|
|||||||
detail=f"Task {task_id} is already {status['status']}"
|
detail=f"Task {task_id} is already {status['status']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate file type
|
|
||||||
if not tracklist_file.filename.endswith(('.txt', '.text')):
|
if not tracklist_file.filename.endswith(('.txt', '.text')):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
detail="Tracklist file must be a text file (.txt or .text)"
|
detail="Tracklist file must be a text file (.txt or .text)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Read and parse the tracklist file
|
|
||||||
try:
|
try:
|
||||||
content = await tracklist_file.read()
|
content = await tracklist_file.read()
|
||||||
text = content.decode('utf-8')
|
text = content.decode('utf-8')
|
||||||
@@ -75,17 +77,13 @@ async def split_from_file(
|
|||||||
detail="Tracklist file is empty"
|
detail="Tracklist file is empty"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Parse the tracklist using CLI logic
|
# Parse tracklist using CLI logic
|
||||||
try:
|
try:
|
||||||
# Parse the format string into tokens
|
|
||||||
tokens = parse_format(tracklist_format)
|
tokens = parse_format(tracklist_format)
|
||||||
|
|
||||||
# Write the content to a temporary file (read_tracklist expects a file path)
|
|
||||||
temp_tracklist_path = settings.temp_dir / task_id / "tracklist.txt"
|
temp_tracklist_path = settings.temp_dir / task_id / "tracklist.txt"
|
||||||
temp_tracklist_path.parent.mkdir(parents=True, exist_ok=True)
|
temp_tracklist_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
temp_tracklist_path.write_text(text, encoding='utf-8')
|
temp_tracklist_path.write_text(text, encoding='utf-8')
|
||||||
|
|
||||||
# Parse the tracklist file using CLI logic
|
|
||||||
tracklist_dicts = read_tracklist(str(temp_tracklist_path), tokens)
|
tracklist_dicts = read_tracklist(str(temp_tracklist_path), tokens)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -100,7 +98,7 @@ async def split_from_file(
|
|||||||
detail="No valid tracks found in tracklist file"
|
detail="No valid tracks found in tracklist file"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Convert dicts to TracklistEntry objects (same as JSON endpoint)
|
# Convert dicts to TracklistEntry objects
|
||||||
try:
|
try:
|
||||||
tracklist_entries = [TracklistEntry(**entry) for entry in tracklist_dicts]
|
tracklist_entries = [TracklistEntry(**entry) for entry in tracklist_dicts]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -109,14 +107,28 @@ async def split_from_file(
|
|||||||
detail=f"Invalid tracklist data: {str(e)}"
|
detail=f"Invalid tracklist data: {str(e)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Parse options JSON
|
# Build options dict from explicit fields (ignore `options` parameter)
|
||||||
try:
|
options = {
|
||||||
options_dict = json.loads(options)
|
"container": container,
|
||||||
except json.JSONDecodeError:
|
"audio_codec": audio_codec,
|
||||||
raise HTTPException(
|
"video_codec": video_codec,
|
||||||
status_code=400,
|
"subtitle_codec": subtitle_codec,
|
||||||
detail="Invalid JSON in options field"
|
"video_quality": video_quality,
|
||||||
)
|
"drop_video": drop_video,
|
||||||
|
"drop_subs": drop_subs,
|
||||||
|
"number_tracks": number_tracks,
|
||||||
|
"replace_bad_chars": replace_bad_chars,
|
||||||
|
"replacement_char": replacement_char,
|
||||||
|
"bad_chars": bad_chars,
|
||||||
|
"skip_existing": skip_existing,
|
||||||
|
"output_template": output_template,
|
||||||
|
"album": album,
|
||||||
|
"comment": comment,
|
||||||
|
"no_comment": no_comment,
|
||||||
|
"comment_stream": comment_stream,
|
||||||
|
"merge_comments": merge_comments,
|
||||||
|
"comment_separator": comment_separator,
|
||||||
|
}
|
||||||
|
|
||||||
# Update task status
|
# Update task status
|
||||||
task_manager.update_task(
|
task_manager.update_task(
|
||||||
@@ -126,12 +138,11 @@ async def split_from_file(
|
|||||||
message="Preparing to split..."
|
message="Preparing to split..."
|
||||||
)
|
)
|
||||||
|
|
||||||
# Start background task
|
|
||||||
background_tasks.add_task(
|
background_tasks.add_task(
|
||||||
run_split_task,
|
run_split_task,
|
||||||
task_id,
|
task_id,
|
||||||
tracklist_entries, # now TracklistEntry objects
|
tracklist_entries,
|
||||||
options_dict
|
options
|
||||||
)
|
)
|
||||||
|
|
||||||
return SplitResponse(
|
return SplitResponse(
|
||||||
|
|||||||
@@ -17,19 +17,16 @@ class TracklistEntry(BaseModel):
|
|||||||
|
|
||||||
@validator("ts")
|
@validator("ts")
|
||||||
def validate_timestamp(cls, v: str) -> str:
|
def validate_timestamp(cls, v: str) -> str:
|
||||||
"""Basic timestamp validation (format and range)."""
|
|
||||||
v = v.strip()
|
v = v.strip()
|
||||||
if not v:
|
if not v:
|
||||||
raise ValueError("Timestamp cannot be empty")
|
raise ValueError("Timestamp cannot be empty")
|
||||||
|
|
||||||
# Check for range format (start-end)
|
|
||||||
if "-" in v:
|
if "-" in v:
|
||||||
parts = v.split("-", 1)
|
parts = v.split("-", 1)
|
||||||
start = parts[0].strip()
|
start = parts[0].strip()
|
||||||
end = parts[1].strip()
|
end = parts[1].strip()
|
||||||
if not start or not end:
|
if not start or not end:
|
||||||
raise ValueError("Invalid range format. Expected 'start-end'")
|
raise ValueError("Invalid range format. Expected 'start-end'")
|
||||||
# Validate each part with the same logic
|
|
||||||
for ts in [start, end]:
|
for ts in [start, end]:
|
||||||
cls._validate_single_timestamp(ts)
|
cls._validate_single_timestamp(ts)
|
||||||
else:
|
else:
|
||||||
@@ -39,7 +36,6 @@ class TracklistEntry(BaseModel):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _validate_single_timestamp(ts: str) -> None:
|
def _validate_single_timestamp(ts: str) -> None:
|
||||||
"""Validate a single timestamp (mm:ss or HH:MM:SS)."""
|
|
||||||
parts = ts.split(":")
|
parts = ts.split(":")
|
||||||
if len(parts) not in (2, 3):
|
if len(parts) not in (2, 3):
|
||||||
raise ValueError(f"Invalid timestamp format: {ts}. Expected mm:ss or HH:MM:SS")
|
raise ValueError(f"Invalid timestamp format: {ts}. Expected mm:ss or HH:MM:SS")
|
||||||
@@ -55,4 +51,30 @@ class SplitRequest(BaseModel):
|
|||||||
|
|
||||||
task_id: str = Field(..., description="Task ID from upload")
|
task_id: str = Field(..., description="Task ID from upload")
|
||||||
tracklist: List[TracklistEntry] = Field(..., description="List of tracks")
|
tracklist: List[TracklistEntry] = Field(..., description="List of tracks")
|
||||||
options: dict = Field(default_factory=dict, description="All CLI options")
|
|
||||||
|
# Container and codec options
|
||||||
|
container: Optional[str] = Field(None, description="Output container (auto-detect if None)")
|
||||||
|
audio_codec: Optional[str] = Field("copy", description="Audio codec (copy or encoder name)")
|
||||||
|
video_codec: Optional[str] = Field("copy", description="Video codec (copy or encoder name)")
|
||||||
|
subtitle_codec: Optional[str] = Field("copy", description="Subtitle codec (copy or encoder name)")
|
||||||
|
video_quality: Optional[int] = Field(None, description="Video quality (encoder-specific integer)")
|
||||||
|
|
||||||
|
# Stream handling
|
||||||
|
drop_video: bool = Field(False, description="Remove video streams")
|
||||||
|
drop_subs: bool = Field(False, description="Remove subtitle streams")
|
||||||
|
|
||||||
|
# Filename options
|
||||||
|
number_tracks: bool = Field(False, description="Prepend track numbers")
|
||||||
|
replace_bad_chars: bool = Field(False, description="Replace bad characters")
|
||||||
|
replacement_char: str = Field("_", description="Replacement character")
|
||||||
|
bad_chars: str = Field(r'!@#№$;:%^&?*(){}[]\/<>+=~`\' ', description="Bad characters to replace")
|
||||||
|
skip_existing: bool = Field(False, description="Skip existing files")
|
||||||
|
output_template: str = Field("%an-%tn.%ext", description="Output filename template")
|
||||||
|
|
||||||
|
# Metadata options
|
||||||
|
album: Optional[str] = Field(None, description="Album name")
|
||||||
|
comment: Optional[str] = Field(None, description="Comment")
|
||||||
|
no_comment: bool = Field(False, description="Ignore comment")
|
||||||
|
comment_stream: Optional[int] = Field(None, description="Comment stream index")
|
||||||
|
merge_comments: bool = Field(False, description="Merge all comments")
|
||||||
|
comment_separator: str = Field("; ", description="Separator for merged comments")
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
"""Business logic services."""
|
"""Business logic services."""
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import SimpleNamespace
|
from typing import List, Dict, Any
|
||||||
from typing import Dict, List, Any
|
import time
|
||||||
|
|
||||||
from backend.config import settings
|
from backend.config import settings
|
||||||
from backend.services.task_manager import task_manager
|
from backend.services.task_manager import task_manager
|
||||||
@@ -13,31 +13,12 @@ from backend.services.file_manager import FileManager
|
|||||||
from backend.models.request import TracklistEntry
|
from backend.models.request import TracklistEntry
|
||||||
from backend.models.response import TaskStatus
|
from backend.models.response import TaskStatus
|
||||||
|
|
||||||
# Import central defaults
|
|
||||||
from audio_splitter.defaults import (
|
|
||||||
DEFAULT_FORMAT,
|
|
||||||
DEFAULT_OUTPUT_TEMPLATE,
|
|
||||||
DEFAULT_REPLACEMENT_CHAR,
|
|
||||||
DEFAULT_BAD_CHARS,
|
|
||||||
DEFAULT_ALBUM,
|
|
||||||
DEFAULT_COMMENT,
|
|
||||||
DEFAULT_NO_COMMENT,
|
|
||||||
DEFAULT_COMMENT_STREAM,
|
|
||||||
DEFAULT_MERGE_COMMENTS,
|
|
||||||
DEFAULT_COMMENT_SEPARATOR,
|
|
||||||
DEFAULT_DROP_VIDEO,
|
|
||||||
DEFAULT_DROP_SUBS,
|
|
||||||
DEFAULT_NUMBER_TRACKS,
|
|
||||||
DEFAULT_REPLACE_BAD_CHARS,
|
|
||||||
DEFAULT_SKIP_EXISTING,
|
|
||||||
DEFAULT_DELETE_ORIGINAL,
|
|
||||||
DEFAULT_TRANSCODE_TO,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[str, Any]) -> None:
|
def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[str, Any]) -> None:
|
||||||
try:
|
try:
|
||||||
task_manager.update_task_with_progress(task_id, progress=5, message="Initializing...")
|
task_manager.update_task_with_progress(
|
||||||
|
task_id, progress=5, message="Initializing..."
|
||||||
|
)
|
||||||
|
|
||||||
input_path = FileManager.get_input_path(task_id)
|
input_path = FileManager.get_input_path(task_id)
|
||||||
if not input_path or not input_path.exists():
|
if not input_path or not input_path.exists():
|
||||||
@@ -45,7 +26,6 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
|
|||||||
|
|
||||||
output_dir = FileManager.ensure_output_dir(task_id)
|
output_dir = FileManager.ensure_output_dir(task_id)
|
||||||
|
|
||||||
# Convert tracklist to dicts (CLI format)
|
|
||||||
tracks = []
|
tracks = []
|
||||||
for entry in tracklist:
|
for entry in tracklist:
|
||||||
track_dict = {
|
track_dict = {
|
||||||
@@ -58,25 +38,30 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
|
|||||||
}
|
}
|
||||||
tracks.append(track_dict)
|
tracks.append(track_dict)
|
||||||
|
|
||||||
# Build args namespace using defaults where options not provided
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
# Build args namespace using the new fields
|
||||||
args = SimpleNamespace(
|
args = SimpleNamespace(
|
||||||
format=options.get("format", DEFAULT_FORMAT),
|
container=options.get("container"), # None -> auto-detect
|
||||||
transcode_to=options.get("transcode_to", DEFAULT_TRANSCODE_TO),
|
audio_codec=options.get("audio_codec", "copy"),
|
||||||
drop_video=options.get("drop_video", DEFAULT_DROP_VIDEO),
|
video_codec=options.get("video_codec", "copy"),
|
||||||
drop_subs=options.get("drop_subs", DEFAULT_DROP_SUBS),
|
subtitle_codec=options.get("subtitle_codec", "copy"),
|
||||||
number_tracks=options.get("number_tracks", DEFAULT_NUMBER_TRACKS),
|
video_quality=options.get("video_quality"),
|
||||||
replace_bad_chars=options.get("replace_bad_chars", DEFAULT_REPLACE_BAD_CHARS),
|
drop_video=options.get("drop_video", False),
|
||||||
replacement_char=options.get("replacement_char", DEFAULT_REPLACEMENT_CHAR),
|
drop_subs=options.get("drop_subs", False),
|
||||||
bad_chars=options.get("bad_chars", DEFAULT_BAD_CHARS),
|
number_tracks=options.get("number_tracks", False),
|
||||||
skip_existing=options.get("skip_existing", DEFAULT_SKIP_EXISTING),
|
replace_bad_chars=options.get("replace_bad_chars", False),
|
||||||
output_template=options.get("output_template", DEFAULT_OUTPUT_TEMPLATE),
|
replacement_char=options.get("replacement_char", "_"),
|
||||||
album=options.get("album", DEFAULT_ALBUM),
|
bad_chars=options.get("bad_chars", r'!@#№$;:%^&?*(){}[]\/<>+=~`\' '),
|
||||||
comment=options.get("comment", DEFAULT_COMMENT),
|
skip_existing=options.get("skip_existing", False),
|
||||||
no_comment=options.get("no_comment", DEFAULT_NO_COMMENT),
|
output_template=options.get("output_template", "%an-%tn.%ext"),
|
||||||
comment_stream=options.get("comment_stream", DEFAULT_COMMENT_STREAM),
|
album=options.get("album", None),
|
||||||
merge_comments=options.get("merge_comments", DEFAULT_MERGE_COMMENTS),
|
comment=options.get("comment", None),
|
||||||
comment_separator=options.get("comment_separator", DEFAULT_COMMENT_SEPARATOR),
|
no_comment=options.get("no_comment", False),
|
||||||
delete_original=DEFAULT_DELETE_ORIGINAL, # never delete in web
|
comment_stream=options.get("comment_stream", None),
|
||||||
|
merge_comments=options.get("merge_comments", False),
|
||||||
|
comment_separator=options.get("comment_separator", "; "),
|
||||||
|
delete_original=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
project_root = Path(__file__).parent.parent.parent.parent
|
project_root = Path(__file__).parent.parent.parent.parent
|
||||||
@@ -85,7 +70,25 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
|
|||||||
|
|
||||||
from audio_splitter.core import split_audio
|
from audio_splitter.core import split_audio
|
||||||
|
|
||||||
task_manager.update_task_with_progress(task_id, progress=10, message="Starting split...")
|
# Detect attached picture and extract if applicable
|
||||||
|
cover_image_path = None
|
||||||
|
if not args.drop_video:
|
||||||
|
from audio_splitter.ffmpeg import is_attached_picture, extract_cover_image, get_stream_info
|
||||||
|
input_path_str = str(input_path)
|
||||||
|
stream_info = get_stream_info(input_path_str)
|
||||||
|
if stream_info.get('has_video') and is_attached_picture(input_path_str):
|
||||||
|
cover_image_path = output_dir / 'cover.png'
|
||||||
|
if extract_cover_image(input_path_str, str(cover_image_path)):
|
||||||
|
print(f"Extracted cover image for task {task_id}")
|
||||||
|
else:
|
||||||
|
cover_image_path = None
|
||||||
|
|
||||||
|
# Attach cover image to args
|
||||||
|
args.cover_image = str(cover_image_path) if cover_image_path else None
|
||||||
|
|
||||||
|
task_manager.update_task_with_progress(
|
||||||
|
task_id, progress=10, message="Starting split..."
|
||||||
|
)
|
||||||
|
|
||||||
split_audio(str(input_path), str(output_dir), tracks, args)
|
split_audio(str(input_path), str(output_dir), tracks, args)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user