openshot_word.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import openshot
  2. import os
  3. import re
  4. import time
  5. import pysrt
  6. import shutil
  7. from PIL import Image,ImageDraw,ImageFont
  8. def cKey(r,g,b,fuzz):
  9. col=openshot.Color()
  10. col.red=openshot.Keyframe(r)
  11. col.green=openshot.Keyframe(g)
  12. col.blue=openshot.Keyframe(b)
  13. return openshot.ChromaKey(col, openshot.Keyframe(fuzz))
  14. def video_writer_init(path):
  15. w = openshot.FFmpegWriter(path)
  16. w.SetAudioOptions(True, "aac", 44100, 2, openshot.LAYOUT_STEREO, 3000000)
  17. w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720,
  18. openshot.Fraction(1, 1), False, False, 3000000)
  19. return w
  20. def video_photo_clip(video=None,layer=None, position=None, end=None
  21. ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True):
  22. clip = openshot.Clip(video)
  23. clip.Layer(layer)
  24. clip.Position(position)
  25. clip.End(end)
  26. clip.scale_x=openshot.Keyframe(scale_x)
  27. clip.scale_y=openshot.Keyframe(scale_y)
  28. clip.location_x=openshot.Keyframe(location_x)
  29. clip.location_y=openshot.Keyframe(location_y)
  30. if ck!=None:
  31. clip.AddEffect(ck)
  32. if audio==True:
  33. clip.has_audio=openshot.Keyframe(1)
  34. else:
  35. clip.has_audio=openshot.Keyframe(0)
  36. return clip
  37. def trim_punctuation(s):
  38. pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'
  39. pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
  40. res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
  41. return res
  42. #文字轉圖片
  43. def txt2image(content, save_target,lang='zh',size=26,fon="font/DFT_B7.ttc"):
  44. unicode_text = trim_punctuation(content)
  45. font = ''
  46. if lang=='zh':
  47. font = ImageFont.truetype(font=fon, size=size)
  48. else :
  49. font = ImageFont.truetype(font="font/arial.ttf", size=size)
  50. W, H = (1280,500)
  51. canvas = Image.new('RGB', (W, H), "#00FF00")
  52. draw = ImageDraw.Draw(canvas)
  53. text= content
  54. if "\n" in text:
  55. w, h = draw.textsize(text.split("\n")[0],font = font)
  56. #draw.text(((W-w)/2,0), text[0:18],'black', font)
  57. text_border(draw,(W-w)/2,0,text.split("\n")[0],font,'black','white')
  58. w, h = draw.textsize(text.split("\n")[1],font = font)
  59. #draw.text(((W-w)/2,h+2), text[18:],'black', font)
  60. text_border(draw,(W-w)/2,h+2,text.split("\n")[1],font,'black','white')
  61. else:
  62. w, h = draw.textsize(content,font = font)
  63. #draw.text(((W-w)/2,0), text,'black', font)
  64. text_border(draw,(W-w)/2,0,text,font,'black','white')
  65. canvas.save(save_target, "PNG")
  66. def text_border(draw,x,y,text,font,shadowcolor,fillcolor):
  67. draw.text((x-1, y), text, font=font, fill=shadowcolor)
  68. draw.text((x+1, y), text, font=font, fill=shadowcolor)
  69. draw.text((x, y-1), text, font=font, fill=shadowcolor)
  70. draw.text((x, y+1), text, font=font, fill=shadowcolor)
  71. draw.text((x-1, y+1), text, font=font, fill=shadowcolor)
  72. draw.text((x+1, y-1), text, font=font, fill=shadowcolor)
  73. draw.text((x-1, y-1), text, font=font, fill=shadowcolor)
  74. draw.text((x+1, y+1), text, font=font, fill=shadowcolor)
  75. # thicker border
  76. draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
  77. draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
  78. draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
  79. draw.text((x+2, y+2), text, font=font, fill=shadowcolor)
  80. # now draw the text over it
  81. draw.text((x, y), text, font=font, fill=fillcolor)
  82. def text_to_short_vedio(mp4_file = "input/example/test3.mp4",sound_file = None
  83. ,vedio_time = 30,output_filename="output/demo.mp4",text_font = "font/DFT_B7.ttc"):
  84. t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
  85. t.Open()
  86. # 去背參數
  87. ck = cKey(0, 254, 0, 270)
  88. ck_anchor = cKey(0, 255, 0, 320)
  89. anchor = openshot.FFmpegReader(mp4_file)
  90. anchor.Open()
  91. anchor_clip = video_photo_clip(video=anchor,layer=2,scale_x=1,scale_y=1,
  92. location_x=0,location_y=0,position=0, end=vedio_time,audio=True)
  93. t.AddClip(anchor_clip)
  94. anchor.Close()
  95. number = 0
  96. sound_srt_file = ""
  97. #音檔自動產生srt(逐字稿)
  98. if ".srt" in sound_file:
  99. sound_srt_file = sound_file
  100. elif not sound_file is None:
  101. cmd = "autosub -S zh-TW -D zh-TW " + sound_file
  102. os.system(cmd)
  103. sound_srt_file = sound_file.split('.')[0] + ".srt"
  104. #開啟srt檔
  105. try:
  106. subs = pysrt.open(sound_srt_file)
  107. text_form = []
  108. for context in subs:
  109. #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
  110. end = context.end-context.start
  111. end_timeStamp=(end.minutes*60+end.seconds+ 0.001*end.milliseconds)
  112. start_timeStamp=(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
  113. text_form.append({'text':context.text,'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
  114. for text_tmp in text_form:
  115. file_name = "tmp/save_target_" + str(number) + ".png"
  116. txt2image(text_tmp['text'], file_name,lang='zh',size = text_tmp['size'],fon = text_tmp['font'])
  117. exec('text_anchor_{} = openshot.QtImageReader("tmp/save_target_{}.png")'.format(number,number))
  118. exec('text_anchor_{}.Open()'.format(number))
  119. exec('text_anchor_{}.Open()'.format(number))
  120. exec('text_anchor_clip_{} = video_photo_clip(video=text_anchor_{},layer=4,scale_x=1,scale_y=1,\
  121. location_x=0,location_y=0.67,position=text_tmp["start"], end=text_tmp["end"],ck=ck_anchor,audio=True)'.format(number,number))
  122. exec('t.AddClip(text_anchor_clip_{})'.format(number))
  123. exec('text_anchor_{}.Close()'.format(number))
  124. number = number+1
  125. except:
  126. print("無法開啟srt檔案(字幕產生失敗)")
  127. w = video_writer_init(output_filename)
  128. w.Open()
  129. frames = int(t.info.fps)*int(vedio_time)
  130. for n in range(frames):
  131. f=t.GetFrame(n)
  132. w.WriteFrame(f)
  133. t.Close()
  134. w.Close()
  135. #刪除暫存檔案
  136. shutil.rmtree('tmp')
  137. os.mkdir('tmp')
  138. if __name__ == '__main__':
  139. text_to_short_vedio(mp4_file = "input/導盲犬影片.mp4",sound_file ='input/導盲犬影片.srt',vedio_time =284,text_font ="font/DFT_R7.ttc")