import os, whisper, asyncio, edge_tts, re, torch from googletrans import Translator from moviepy.editor import VideoFileClip, AudioFileClip, CompositeAudioClip import moviepy.video.fx.all as vfx # --- ⚙️ ការកំណត់ --- Video_Name = "movie.mp4" VIDEO_PATH = f"input_video/{Video_Name}" OUTPUT_PATH = f"final_result/BM7_ULTIMATE_DUB_{Video_Name}" translator = Translator() def detect_gender(text): # បន្ថែមពាក្យគន្លឹះឱ្យកាន់តែច្រើនដើម្បីភាពត្រឹមត្រូវ female_keywords = ['នាង', 'ស្រី', 'អូន', 'អ្នកនាង', 'កញ្ញា', 'ម៉ាក់', 'យាយ', 'ព្រះនាង', 'មីង'] if any(word in text for word in female_keywords): return "km-KH-SreymomNeural" return "km-KH-PisethNeural" def professional_khmer_filter(text): try: # ១. លុបពាក្យដដែលៗចេញពី Whisper text = re.sub(r'\b(\w+)( \1\b)+', r'\1', text) # ២. បកប្រែ raw_kh = translator.translate(text, src='zh-cn', dest='km').text # ៣. កែសម្រួលតាមបរិបទខ្មែរ corrections = { "អ្នក": "ឯង", "ខ្ញុំ": "យើង", "សួស្តី": "ជម្រាបសួរ", "អរគុណ": "អរគុណច្រើន", "មែនទេ": "មែនអត់?", "ពិតជា": "ពិតមែនហើយ", "បាទ": "បាទ/ចា៎", "តើអ្នកសុខសប្បាយជាទេ": "សុខសប្បាយអត់?" } for old, new in corrections.items(): raw_kh = raw_kh.replace(old, new) # លុបសញ្ញាខណ្ឌដែលនាំឱ្យ AI អានឈប់យូរពេក raw_kh = re.sub(r'[.!?៖។]', ' ', raw_kh) return " ".join(raw_kh.split()) # លុប Space ដែលលើស except: return "" async def generate_smooth_audio(text, start, duration, index): try: kh_text = professional_khmer_filter(text) if not kh_text or len(kh_text) < 2: return None, None voice = detect_gender(kh_text) tmp = f"tmp_{index}.mp3" # កែសម្រួល Pitch និង Rate communicate = edge_tts.Communicate(kh_text, voice, rate="+10%", pitch="-1Hz") await communicate.save(tmp) # បន្ថែម Fade ឱ្យសំឡេងចូលមកស្រទន់ audio = AudioFileClip(tmp).set_start(start).volumex(5.2).audio_fadein(0.05).audio_fadeout(0.05) # គ្រប់គ្រងល្បឿន actual_dur = audio.duration target_dur = duration if actual_dur > target_dur: audio = vfx.speedx(audio, factor=actual_dur/target_dur).set_duration(target_dur) elif actual_dur < (target_dur * 0.6): # បើខ្លីពេក ឱ្យវាអានមួយៗ (Slow down) audio = vfx.speedx(audio, factor=actual_dur/(target_dur * 0.8)).set_duration(target_dur * 0.8) return audio, tmp except: return None, None async def start_dubbing(): if not os.path.exists(VIDEO_PATH): print("❌ រកមិនឃើញ File ទេ!"); return print("🚀 កំពុងដំណើរការ AI (Medium Model)...") device = "cuda" if torch.cuda.is_available() else "cpu" model = whisper.load_model("medium").to(device) # កំណត់កម្រិតស្ដាប់ឱ្យហ្មត់ចត់ transcribe = model.transcribe( VIDEO_PATH, task="transcribe", language="zh", temperature=0, beam_size=5, compression_ratio_threshold=2.4 ) segments = transcribe['segments'] video = VideoFileClip(VIDEO_PATH) audio_tracks = [video.audio.volumex(0.10)] # បន្ថយសំឡេងដើមមកត្រឹម ១០% temp_files = [] print(f"🎙️ កំពុងផលិតសំឡេងបកប្រែ {len(segments)} ឃ្លា...") # ប្រើ Loop ដើម្បីស្ថេរភាព RAM for i, s in enumerate(segments): aud, path = await generate_smooth_audio(s['text'], s['start'], s['end']-s['start'], i) if aud: audio_tracks.append(aud) temp_files.append(path) if i % 25 == 0: print(f"⏳ Progress: {round((i/len(segments))*100)}%...") print("🎬 កំពុងចងក្រងវីដេអូសម្រេច (High Quality)...") final_audio = CompositeAudioClip(audio_tracks) final_video = video.set_audio(final_audio) # ប្រើ threads=4 ដើម្បីល្បឿន និង preset=ultrafast បើចង់បានលឿន final_video.write_videofile(OUTPUT_PATH, codec="libx264", audio_codec="aac", threads=4, fps=video.fps) # សម្អាត File បណ្ដោះអាសន្ន video.close() for f in temp_files: try: if os.path.exists(f): os.remove(f) except: pass print(f"✅ ជោគជ័យមហាអស្ចារ្យម្ចាស់គ្រូ! វីដេអូរួចរាល់៖ {OUTPUT_PATH}") if __name__ == "__main__": # បើកដំណើរការ Async loop = asyncio.get_event_loop() loop.run_until_complete(start_dubbing())
    Blogger Comment
    Facebook Comment

0 comments:

Post a Comment

 
Copyright © 2026. BM7//ANGKOR - All Rights Reserved
Template Created by ThemeXpose | BM7//ANGKOR