@@ -12,6 +12,7 @@ async def convert_to_mp3_ffmpeg(
1212 output_path : Optional [Path ] = None ,
1313 format : str = "mp3" ,
1414 use_memory_profiler : bool = False ,
15+ speedup : Optional [float ] = None ,
1516) -> Path :
1617 """
1718 Convert video file to audio using ffmpeg.
@@ -21,15 +22,16 @@ async def convert_to_mp3_ffmpeg(
2122 output_path: Path to save the audio file (optional)
2223 format: Audio format (default: mp3)
2324 use_memory_profiler: Whether to use memory profiler implementation
25+ speedup: Audio speedup factor (e.g., 2.0 for 2x speed)
2426
2527 Returns:
2628 Path to the converted audio file
2729 """
28- # If the file is already an audio file, return it as is
30+ # If the file is already an audio file and no speedup is requested , return it as is
2931 # if source_path.suffix.lower() in [".mp3", ".wav", ".ogg", ".m4a", ".flac"]:
3032 # logger.info(f"File {source_path} is already an audio file, skipping conversion")
3133 # return source_path
32- if source_path .suffix .lower () == ".mp3" :
34+ if source_path .suffix .lower () == ".mp3" and speedup is None :
3335 logger .info (f"File { source_path } is already an audio file, skipping conversion" )
3436 return source_path
3537
@@ -42,13 +44,13 @@ async def convert_to_mp3_ffmpeg(
4244
4345 # Choose the appropriate implementation based on the flag
4446 if use_memory_profiler :
45- return await _convert_to_mp3_with_profiler (source_path , output_path , format )
47+ return await _convert_to_mp3_with_profiler (source_path , output_path , format , speedup )
4648 else :
47- return await _convert_to_mp3_standard (source_path , output_path , format )
49+ return await _convert_to_mp3_standard (source_path , output_path , format , speedup )
4850
4951
5052async def _convert_to_mp3_standard (
51- source_path : Path , output_path : Path , format : str = "mp3"
53+ source_path : Path , output_path : Path , format : str = "mp3" , speedup : Optional [ float ] = None
5254) -> Path :
5355 """
5456 Standard implementation of video to audio conversion using ffmpeg.
@@ -57,6 +59,7 @@ async def _convert_to_mp3_standard(
5759 source_path: Path to the video file
5860 output_path: Path to save the audio file
5961 format: Audio format (default: mp3)
62+ speedup: Audio speedup factor (e.g., 2.0 for 2x speed)
6063
6164 Returns:
6265 Path to the converted audio file
@@ -72,13 +75,32 @@ async def _convert_to_mp3_standard(
7275 "-i" ,
7376 str (source_path ), # Input file
7477 "-vn" , # Disable video
78+ ]
79+
80+ # Add speedup filter if requested
81+ if speedup is not None :
82+ # For speedup > 2.0, chain multiple atempo filters for better quality
83+ if speedup > 2.0 :
84+ # Calculate how many atempo filters we need
85+ temp_speedup = speedup
86+ filters = []
87+ while temp_speedup > 2.0 :
88+ filters .append ("atempo=2.0" )
89+ temp_speedup /= 2.0
90+ if temp_speedup > 1.0 :
91+ filters .append (f"atempo={ temp_speedup } " )
92+ cmd .extend (["-filter:a" , "," .join (filters )])
93+ else :
94+ cmd .extend (["-filter:a" , f"atempo={ speedup } " ])
95+
96+ cmd .extend ([
7597 "-acodec" ,
7698 "libmp3lame" if format == "mp3" else format , # Audio codec
7799 "-q:a" ,
78100 "2" , # Audio quality (0-9, 0=best)
79101 "-y" , # Overwrite output file if it exists
80102 str (output_path ), # Output file
81- ]
103+ ])
82104
83105 # Run the command
84106 process = subprocess .Popen (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
@@ -99,7 +121,7 @@ async def _convert_to_mp3_standard(
99121
100122
101123async def _convert_to_mp3_with_profiler (
102- source_path : Path , output_path : Path , format : str = "mp3"
124+ source_path : Path , output_path : Path , format : str = "mp3" , speedup : Optional [ float ] = None
103125) -> Path :
104126 """
105127 Memory-profiled implementation of video to audio conversion using ffmpeg.
@@ -108,6 +130,7 @@ async def _convert_to_mp3_with_profiler(
108130 source_path: Path to the video file
109131 output_path: Path to save the audio file
110132 format: Audio format (default: mp3)
133+ speedup: Audio speedup factor (e.g., 2.0 for 2x speed)
111134
112135 Returns:
113136 Path to the converted audio file
@@ -121,13 +144,32 @@ async def _convert_to_mp3_with_profiler(
121144 "-i" ,
122145 str (source_path ), # Input file
123146 "-vn" , # Disable video
147+ ]
148+
149+ # Add speedup filter if requested
150+ if speedup is not None :
151+ # For speedup > 2.0, chain multiple atempo filters for better quality
152+ if speedup > 2.0 :
153+ # Calculate how many atempo filters we need
154+ temp_speedup = speedup
155+ filters = []
156+ while temp_speedup > 2.0 :
157+ filters .append ("atempo=2.0" )
158+ temp_speedup /= 2.0
159+ if temp_speedup > 1.0 :
160+ filters .append (f"atempo={ temp_speedup } " )
161+ cmd .extend (["-filter:a" , "," .join (filters )])
162+ else :
163+ cmd .extend (["-filter:a" , f"atempo={ speedup } " ])
164+
165+ cmd .extend ([
124166 "-acodec" ,
125167 "libmp3lame" if format == "mp3" else format , # Audio codec
126168 "-q:a" ,
127169 "2" , # Audio quality (0-9, 0=best)
128170 "-y" , # Overwrite output file if it exists
129171 str (output_path ), # Output file
130- ]
172+ ])
131173
132174 # Start memory profiling
133175 memory_stats = []
0 commit comments