| import gradio as gr |
| import ffmpeg |
| import os |
| import tempfile |
|
|
| def compress_video(input_path, target_bitrate, target_width): |
| |
| probe = ffmpeg.probe(input_path) |
| video_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'video'] |
| if not video_streams: |
| raise ValueError("No video stream found in the uploaded file.") |
|
|
| orig_width = int(video_streams[0]['width']) |
| orig_height = int(video_streams[0]['height']) |
|
|
| |
| new_width = int(target_width) |
| new_height = int(orig_height * new_width / orig_width) |
| |
| if new_height % 2 != 0: |
| new_height += 1 |
|
|
| |
| out_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") |
| output_path = out_file.name |
| out_file.close() |
|
|
| |
| ( |
| ffmpeg |
| .input(input_path) |
| .output( |
| output_path, |
| video_bitrate=f'{target_bitrate}k', |
| vf=f'scale={new_width}:{new_height}', |
| audio_bitrate='128k', |
| preset='medium' |
| ) |
| .run(overwrite_output=True) |
| ) |
|
|
| return output_path |
|
|
|
|
| def process_video(input_path, target_bitrate, target_width): |
| |
| compressed_path = compress_video(input_path, target_bitrate, target_width) |
| return compressed_path |
|
|
|
|
| def main(): |
| with gr.Blocks() as demo: |
| gr.Markdown("# Video Compressor App") |
|
|
| with gr.Row(): |
| input_video = gr.Video(label="Upload Video") |
| target_bitrate = gr.Slider( |
| minimum=100, |
| maximum=5000, |
| step=100, |
| value=1000, |
| label="Target Video Bitrate (kbps)" |
| ) |
| target_width = gr.Slider( |
| minimum=240, |
| maximum=1920, |
| step=16, |
| value=640, |
| label="Target Width (px)" |
| ) |
|
|
| compress_button = gr.Button("Compress") |
| output_video = gr.File(label="Download Compressed Video") |
|
|
| compress_button.click( |
| fn=process_video, |
| inputs=[input_video, target_bitrate, target_width], |
| outputs=output_video |
| ) |
|
|
| demo.launch() |
|
|
| if __name__ == "__main__": |
| main() |