openshot_word.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import openshot
  2. import os
  3. import re
  4. import time
  5. import pysrt
  6. import shutil
  7. from datetime import datetime
  8. from PIL import Image,ImageDraw,ImageFont
  9. import gspread
  10. import pandas as pd
  11. from oauth2client.service_account import ServiceAccountCredentials
  12. def auth_gss_client(path, scopes):
  13. credentials = ServiceAccountCredentials.from_json_keyfile_name(path, scopes)
  14. return gspread.authorize(credentials)
  15. auth_json_path = 'noted-tesla-348011-74f70c9caeda.json' #由剛剛建立出的憑證,放置相同目錄以供引入
  16. gss_scopes = ['https://spreadsheets.google.com/feeds'] #我們想要取用的範圍
  17. gss_client = auth_gss_client(auth_json_path, gss_scopes) #呼叫我們的函式
  18. #從剛剛建立的sheet,把網址中 https://docs.google.com/spreadsheets/d/〔key〕/edit 的 〔key〕的值代入
  19. spreadsheet_key_path = '1LU5O8-oAotIFGPI9STPbElO0NHGA6eynuv9sYz81aOw'
  20. wks = gss_client.open_by_key(spreadsheet_key_path).sheet1
  21. def srt_to_sheet(srt_file):
  22. subs = pysrt.open(srt_file)
  23. wks.clear()
  24. index = 0
  25. for context in subs:
  26. index = context.index
  27. cell_list = wks.range('A1:C'+str(index))
  28. number = 0
  29. for context in subs:
  30. #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
  31. index = context.index
  32. end = context.end
  33. start = context.start
  34. #print('A'+str(index))
  35. cell_list[number].value = str(start)
  36. cell_list[number+1].value = str(end)
  37. cell_list[number+2].value = str(context.text)
  38. number = number+3
  39. wks.update_cells(cell_list)
  40. def sheet_to_text(text_font):
  41. ck_anchor = cKey(0, 255, 0, 320)
  42. text_form = []
  43. for context in wks.get_all_values():
  44. #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
  45. start = datetime.strptime(context[0], "%H:%M:%S,%f")
  46. end = datetime.strptime(context[1], "%H:%M:%S,%f") - datetime.strptime(context[0], "%H:%M:%S,%f")
  47. end_timeStamp=end.seconds+0.000001*end.microseconds
  48. start_timeStamp=start.minute*60+start.second+ 0.000001*start.microsecond
  49. text_form.append({'text':context[2],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
  50. print({'text':context[2],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
  51. def cKey(r,g,b,fuzz):
  52. col=openshot.Color()
  53. col.red=openshot.Keyframe(r)
  54. col.green=openshot.Keyframe(g)
  55. col.blue=openshot.Keyframe(b)
  56. return openshot.ChromaKey(col, openshot.Keyframe(fuzz))
  57. def video_writer_init(path):
  58. w = openshot.FFmpegWriter(path)
  59. w.SetAudioOptions(True, "aac", 44100, 2, openshot.LAYOUT_STEREO, 3000000)
  60. w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720,
  61. openshot.Fraction(1, 1), False, False, 3000000)
  62. return w
  63. def video_photo_clip(video=None,layer=None, position=None, end=None
  64. ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True):
  65. clip = openshot.Clip(video)
  66. clip.Layer(layer)
  67. clip.Position(position)
  68. clip.End(end)
  69. clip.scale_x=openshot.Keyframe(scale_x)
  70. clip.scale_y=openshot.Keyframe(scale_y)
  71. clip.location_x=openshot.Keyframe(location_x)
  72. clip.location_y=openshot.Keyframe(location_y)
  73. if ck!=None:
  74. clip.AddEffect(ck)
  75. if audio==True:
  76. clip.has_audio=openshot.Keyframe(1)
  77. else:
  78. clip.has_audio=openshot.Keyframe(0)
  79. return clip
  80. def trim_punctuation(s):
  81. pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'
  82. pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
  83. res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
  84. return res
  85. #文字轉圖片
  86. def txt2image(content, save_target,lang='zh',size=26,fon="font/DFT_B7.ttc"):
  87. unicode_text = trim_punctuation(content)
  88. font = ''
  89. if lang=='zh':
  90. font = ImageFont.truetype(font=fon, size=size)
  91. else :
  92. font = ImageFont.truetype(font="font/arial.ttf", size=size)
  93. W, H = (1280,500)
  94. canvas = Image.new('RGB', (W, H), "#00FF00")
  95. draw = ImageDraw.Draw(canvas)
  96. text= content
  97. if "\n" in text:
  98. w, h = draw.textsize(text.split("\n")[0],font = font)
  99. #draw.text(((W-w)/2,0), text[0:18],'black', font)
  100. text_border(draw,(W-w)/2,0,text.split("\n")[0],font,'black','white')
  101. w, h = draw.textsize(text.split("\n")[1],font = font)
  102. #draw.text(((W-w)/2,h+2), text[18:],'black', font)
  103. text_border(draw,(W-w)/2,h+2,text.split("\n")[1],font,'black','white')
  104. else:
  105. w, h = draw.textsize(content,font = font)
  106. #draw.text(((W-w)/2,0), text,'black', font)
  107. text_border(draw,(W-w)/2,0,text,font,'black','white')
  108. canvas.save(save_target, "PNG")
  109. def text_border(draw,x,y,text,font,shadowcolor,fillcolor):
  110. draw.text((x-1, y), text, font=font, fill=shadowcolor)
  111. draw.text((x+1, y), text, font=font, fill=shadowcolor)
  112. draw.text((x, y-1), text, font=font, fill=shadowcolor)
  113. draw.text((x, y+1), text, font=font, fill=shadowcolor)
  114. draw.text((x-1, y+1), text, font=font, fill=shadowcolor)
  115. draw.text((x+1, y-1), text, font=font, fill=shadowcolor)
  116. draw.text((x-1, y-1), text, font=font, fill=shadowcolor)
  117. draw.text((x+1, y+1), text, font=font, fill=shadowcolor)
  118. # thicker border
  119. draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
  120. draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
  121. draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
  122. draw.text((x+2, y+2), text, font=font, fill=shadowcolor)
  123. # now draw the text over it
  124. draw.text((x, y), text, font=font, fill=fillcolor)
  125. def text_to_short_vedio(mp4_file = "input/example/test3.mp4",sound_file = None
  126. ,vedio_time = 30,output_filename="output/demo.mp4",text_font = "font/DFT_B7.ttc"):
  127. t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
  128. t.Open()
  129. # 去背參數
  130. ck = cKey(0, 254, 0, 270)
  131. ck_anchor = cKey(0, 255, 0, 320)
  132. anchor = openshot.FFmpegReader(mp4_file)
  133. anchor.Open()
  134. anchor_clip = video_photo_clip(video=anchor,layer=2,scale_x=1,scale_y=1,
  135. location_x=0,location_y=0,position=0, end=vedio_time,audio=True)
  136. t.AddClip(anchor_clip)
  137. anchor.Close()
  138. number = 0
  139. sound_srt_file = ""
  140. #音檔自動產生srt(逐字稿)
  141. if ".srt" in sound_file:
  142. sound_srt_file = sound_file
  143. elif not sound_file is None:
  144. cmd = "autosub -S zh-TW -D zh-TW " + sound_file
  145. os.system(cmd)
  146. sound_srt_file = sound_file.split('.')[0] + ".srt"
  147. #開啟srt檔
  148. try:
  149. srt_to_sheet(sound_file)
  150. text_form = sheet_to_text(text_font)
  151. number = 0
  152. for text_tmp in text_form:
  153. file_name = "tmp/save_target_" + str(number) + ".png"
  154. txt2image(text_tmp['text'], file_name,lang='zh',size = text_tmp['size'],fon = text_tmp['font'])
  155. exec('text_anchor_{} = openshot.QtImageReader("tmp/save_target_{}.png")'.format(number,number))
  156. exec('text_anchor_{}.Open()'.format(number))
  157. exec('text_anchor_{}.Open()'.format(number))
  158. exec('text_anchor_clip_{} = video_photo_clip(video=text_anchor_{},layer=4,scale_x=1,scale_y=1,\
  159. location_x=0,location_y=0.67,position=text_tmp["start"], end=text_tmp["end"],ck=ck_anchor,audio=True)'.format(number,number))
  160. exec('t.AddClip(text_anchor_clip_{})'.format(number))
  161. exec('text_anchor_{}.Close()'.format(number))
  162. number = number+1
  163. except:
  164. print("無法開啟srt檔案(字幕產生失敗)")
  165. w = video_writer_init(output_filename)
  166. w.Open()
  167. frames = int(t.info.fps)*int(vedio_time)
  168. for n in range(frames):
  169. f=t.GetFrame(n)
  170. w.WriteFrame(f)
  171. t.Close()
  172. w.Close()
  173. #刪除暫存檔案
  174. shutil.rmtree('tmp')
  175. os.mkdir('tmp')
  176. if __name__ == '__main__':
  177. text_to_short_vedio(mp4_file = "input/example/導盲犬_投影片2.mp4",sound_file ='input/example/導盲犬_投影片2.srt',vedio_time =110,text_font ="font/DFT_R7.ttc")
  178. #srt_to_sheet('input/example/導盲犬_投影片2.srt')
  179. #sheet_to_text("font/DFT_R7.ttc")