China Movies Speak Khmer.
May 03, 2026
1
# ដំឡើងគ្រឿងបន្លាស់ដែលបាត់ (ម្ចាស់គ្រូត្រូវរត់អាហ្នឹងមុនគេ)
!pip install openai-whisper edge-tts googletrans==4.0.0-rc1 moviepy==1.0.3
2
#@title 🪄 ម៉ាស៊ីនបកប្រែវីដេអូ - គ្រូអាគម AI
import os
# --- ផ្នែកបង្កើតប៊ូតុងសម្រាប់បញ្ចូលឈ្មោះ (Forms) ---
Video_Name = "movie.mp4" #@param {type:"string"}
Language = "Khmer" #@param ["Khmer", "English", "Chinese"]
def create_project_folders():
folders = ['input_video', 'output_audio', 'final_result']
for folder in folders:
if not os.path.exists(folder):
os.makedirs(folder)
print(f"✅ បង្កើត Folder: {folder} រួចរាល់!")
else:
print(f"📂 Folder: {folder} មានរួចហើយ។")
if __name__ == "__main__":
print(f"--- 🧙♂️ ចាប់ផ្ដើមរៀបចំសម្រាប់វីដេអូ: {Video_Name} ---")
create_project_folders()
# បង្ហាញផ្លូវដែលត្រូវដាក់វីដេអូឱ្យមិត្តភក្តិឃើញច្បាស់ៗ
path = os.path.join('input_video', Video_Name)
print(f"--- 👉 friend ត្រូវយកវីដេអូទៅដាក់ក្នុង: {path} ---")
3
import os, whisper, asyncio, edge_tts, re
from googletrans import Translator
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeAudioClip
import moviepy.video.fx.all as vfx
# --- ⚙️ កំណត់រចនាសម្ព័ន្ធ ---
Video_Name = "PRO_AI_DUB_BM7.mp4"
VIDEO_PATH = f"input_video/{Video_Name}"
OUTPUT_PATH = f"final_result/CHARACTER_DUB_{Video_Name}"
translator = Translator()
# --- 🎙️ បញ្ជីសំឡេងតួអង្គ ---
VOICES = {
"MALE": "km-KH-PisethNeural",
"FEMALE": "km-KH-SreymomNeural"
}
# --- 🧠 ម៉ាស៊ីនវិភាគតួអង្គ និងកែសម្រួលភាសា ---
def identify_and_filter(text):
# ១. បកប្រែជាមុនសិន
raw_kh = translator.translate(text, src='zh-cn', dest='km').text
# ២. កំណត់ភេទតួអង្គតាមរយៈពាក្យគន្លឹះ (Heuristic Detection)
# បើមានពាក្យ "នាង" "ស្រី" "ព្រះនាង" យើងនឹងប្រើសំឡេងស្រី
female_keywords = ['នាង', 'ស្រី', 'ព្រះនាង', 'អ្នកនាង', 'ម៉ាក់', 'បងស្រី', 'អូន']
gender = "MALE"
if any(word in raw_kh for word in female_keywords):
gender = "FEMALE"
# ៣. កែសម្រួលពាក្យឱ្យសមជាតួអង្គក្នុងរឿង (Drama Style)
corrections = {
"អ្នក": "ឯង", "ខ្ញុំ": "យើង",
"តើអ្នកកំពុងធ្វើអ្វី": "ឯងកំពុងធ្វើស្អី?",
"ពិតជា": "ពិតមែនហើយ", "មិនអាច": "មិនបានទេ",
"តើមានរឿងអ្វី": "មានរឿងអី?"
}
for old, new in corrections.items():
raw_kh = raw_kh.replace(old, new)
return raw_kh.strip(), gender
async def generate_character_audio(text, start, duration):
try:
kh_text, gender = identify_and_filter(text)
if not kh_text: return None, None
selected_voice = VOICES[gender]
# កំណត់ Pitch ឱ្យខុសគ្នាបន្តិចៗតាមឃ្លា ដើម្បីកុំឱ្យសំឡេងដូចគ្នាច្រើនពេក
pitch = "-1Hz" if gender == "MALE" else "+1Hz"
tmp = f"tmp_{start}.mp3"
communicate = edge_tts.Communicate(kh_text, selected_voice, rate="+7%", pitch=pitch)
await communicate.save(tmp)
audio = AudioFileClip(tmp).set_start(start).volumex(4.5)
if audio.duration > duration:
return vfx.speedx(audio, factor=audio.duration/duration).set_duration(duration), tmp
return audio, tmp
except Exception as e:
print(f"Error: {e}")
return None, None
async def start_multi_dubbing():
# ១. ស្កែនវីដេអូ
model = whisper.load_model("medium")
print("🔍 កំពុងវិភាគសាច់រឿង និងតួអង្គ...")
transcribe = model.transcribe(VIDEO_PATH, task="transcribe", language="zh")
# ២. រៀបចំ Segment
segments = transcribe['segments']
video = VideoFileClip(VIDEO_PATH)
audio_tracks = [video.audio.volumex(0.15)]
# ៣. បង្កើតសំឡេងតាមតួអង្គ
print(f"🎬 កំពុងបញ្ចូលសំឡេងតួអង្គក្នុង {Video_Name}...")
tasks = [generate_character_audio(s['text'], s['start'], s['end']-s['start']) for s in segments]
results = await asyncio.gather(*tasks)
temp_files = []
for aud, path in results:
if aud:
audio_tracks.append(aud)
temp_files.append(path)
# ៤. បញ្ចប់ការងារ
final_audio = CompositeAudioClip(audio_tracks)
final_video = video.set_audio(final_audio)
final_video.write_videofile(OUTPUT_PATH, codec="libx264", audio_codec="aac")
for f in temp_files:
if os.path.exists(f): os.remove(f)
print(f"✅ រួចរាល់! វីដេអូបំបែកសំឡេងតួអង្គ៖ {OUTPUT_PATH}")
if __name__ == "__main__":
await start_multi_dubbing()
- Blogger Comment
- Facebook Comment

0 comments:
Post a Comment