Parcourir la source

上傳檔案到 'AI_anchor2'

oak il y a 2 ans
Parent
commit
d5d840a1c2
5 fichiers modifiés avec 625 ajouts et 0 suppressions
  1. 39 0
      AI_anchor2/Dockerfile
  2. 509 0
      AI_anchor2/main.py
  3. 11 0
      AI_anchor2/readme.md
  4. 44 0
      AI_anchor2/sample.csv
  5. 22 0
      AI_anchor2/sample_explain.csv

+ 39 - 0
AI_anchor2/Dockerfile

@@ -0,0 +1,39 @@
+FROM ubuntu:20.04
+
+RUN apt update
+RUN apt install -y software-properties-common
+RUN add-apt-repository -y ppa:openshot.developers/ppa
+RUN apt update
+RUN DEBIAN_FRONTEND=noninteractive apt-get install keyboard-configuration -y
+RUN apt-get update && apt-get install -y apt-transport-https
+RUN apt-get upgrade -y
+RUN apt install ffmpeg -y
+RUN apt-get install python3-pip -y
+RUN apt install -y python3-openshot openshot-qt
+RUN apt-get install vim -y
+RUN pip3 install fastapi
+RUN pip3 install uvicorn[standard]
+RUN pip3 install numpy==1.19.2
+RUN pip3 install BeautifulSoup4
+RUN pip3 install Pillow
+RUN pip3 install pyttsx3
+RUN pip3 install zhtts
+RUN pip3 install rpyc
+RUN pip3 install websocket
+RUN pip3 install websocket-client
+RUN pip3 install dataset
+RUN pip3 install aiofiles
+RUN apt-get install python3-openshot -y
+#RUN apt-get install openshot-qt -y
+RUN apt install -y xvfb
+RUN pip3 install gtts
+RUN pip3 install ffmpy
+RUN pip3 install --upgrade google-api-python-client
+RUN pip3 install progressbar
+RUN pip3 install pysrt
+RUN apt install -y xvfb
+RUN pip3 install pandas
+RUN pip3 install opencv-contrib-python
+RUN pip3 install autosub
+RUN pip3 install autosub3
+RUN pip3 install openpyxl

+ 509 - 0
AI_anchor2/main.py

@@ -0,0 +1,509 @@
+import openshot
+import re
+from PIL import Image,ImageDraw,ImageFont
+import pandas as pd
+import os
+import cv2
+import numpy as np
+# import moviepy.editor as mp
+import time
+import pysrt
+import shutil
+import rpyc
+import random
+import string
+import requests
+from bs4 import BeautifulSoup
+import zipfile
+import csv
+from datetime import datetime
+def cKey(r,g,b,fuzz):
+    col=openshot.Color()
+    col.red=openshot.Keyframe(r)
+    col.green=openshot.Keyframe(g)
+    col.blue=openshot.Keyframe(b)
+    return openshot.ChromaKey(col, openshot.Keyframe(fuzz))
+
+def video_writer_init(path):
+    w = openshot.FFmpegWriter(path)
+    w.SetAudioOptions(True, "aac", 44100, 2, openshot.LAYOUT_STEREO, 3000000)
+    w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720,
+        openshot.Fraction(1, 1), False, False, 3000000)
+    return w
+
+def video_photo_clip(video=None,layer=None, position=None, end=None
+    ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True):
+    clip = openshot.Clip(video)
+    clip.Layer(layer)
+    clip.Position(position)
+    clip.End(end)
+    clip.scale_x=openshot.Keyframe(scale_x)
+    clip.scale_y=openshot.Keyframe(scale_y)
+    clip.location_x=openshot.Keyframe(location_x)
+    clip.location_y=openshot.Keyframe(location_y)
+    
+    if ck!=None:
+        clip.AddEffect(ck)
+    if audio==True:
+        clip.has_audio=openshot.Keyframe(1)
+    else:
+        clip.has_audio=openshot.Keyframe(0)
+    return clip
+
+def trim_punctuation(s):
+    pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'
+    pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
+    res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
+    return res
+
+
+def randomString(stringLength=10):
+    letters = string.ascii_lowercase
+    return ''.join(random.choice(letters) for i in range(stringLength))
+
+
+def mp3_to_anchor(fname):
+
+    conn = rpyc.classic.connect("192.168.192.221",18812)
+    fr=open(fname,'rb')
+    ropen = conn.builtins.open
+    randname=randomString(10)
+    finalname=randomString(10)
+
+    fw=ropen('/tmp/'+randname+'.mp4','wb')
+    fw.write(fr.read())
+    fw.close()
+    ros = conn.modules.os
+    ros.system('/root/to_video/p9.sh '+randname+".mp4 "+finalname+".mp4")
+    return 'http://192.168.192.221/video/'+finalname+'.mp4'
+#    conn.execute('import os')
+
+
+def download_mp4(url):
+    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'}
+    with open('input_self/AI_girl/ai_spokesgirl.mp4','wb') as f:
+        r = requests.get(url, headers=headers, stream=True)
+        if r.status_code == 404:
+            return False
+        for chunk in r.iter_content(chunk_size=1024):
+            if chunk:
+                f.write(chunk)
+    return True
+
+
+
+                
+   
+ 
+
+def text_to_short_vedio_create(read_csv_use="導盲犬協會.csv",pwd_use="導盲犬協會影片素材2/",op="input_self/LOGO_OP_4.mp4",ed="input_self/LOGO_ED.mp4",bg="input_self/bg_finall_long.mp4",input_zip="input/input_data.zip"):
+    t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
+    t.Open()
+
+    files=os.listdir("input/")
+    print(files)
+    for i in files:
+        if i[-4:]==".zip":
+            input_zip="input/"+i
+            break
+
+    # try:
+    #     os.remove("./templates/index.html")
+    # except:
+    #     pass
+    with zipfile.ZipFile(input_zip, 'r') as zf:
+        for fn in zf.namelist():
+
+            right_fn = fn.encode('cp437').decode('big5')  # 將檔名正確編碼
+            check_p=right_fn.split("/")
+            if right_fn[-1]=="/" :
+                os.mkdir("input/"+right_fn[:-1])
+                pwd_use=right_fn
+                break
+            if len(check_p)==2:
+                os.mkdir("input/"+check_p[0])
+                pwd_use=check_p[0]+"/"
+                break
+
+    with zipfile.ZipFile(input_zip, 'r') as zf:
+        for fn in zf.namelist():
+            right_fn = fn.encode('cp437').decode('big5')  # 將檔名正確編碼
+            check_p=right_fn.split("/")
+            if right_fn[-1]=="/" :
+                continue
+            if right_fn[-4:]==".csv":
+                read_csv_use = right_fn
+            with open("input/"+right_fn, 'wb') as output_file:  # 建立並開啟新檔案
+                with zf.open(fn, 'r') as origin_file:  # 開啟原檔案
+                    shutil.copyfileobj(origin_file, output_file)  # 將原檔案內容複製到新檔案
+
+
+
+
+
+    # 去背參數
+    # ck=cKey(0,254,0,270)
+    ck=cKey(0,255,0,320)
+    ck_anchor=None
+    #時間
+    time_= 0
+    
+    csv_use=pd.read_csv("input/"+read_csv_use)
+    csv_use=csv_use.dropna(how='all')
+    csv_use.reset_index(inplace=True)
+
+
+
+    t1 = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
+    t1.Open()
+
+    frames = 0
+    for i in range(len(csv_use)):
+    # for i in range(3):
+        pwd_=str(csv_use.loc[i,['音檔']].values[0])
+
+        
+        locals()['anchor_music_t'+str(i)] = openshot.FFmpegReader("input/"+pwd_use+pwd_)
+        locals()['anchor_music_t'+str(i)].Open()
+        locals()['anchor_music_t'+str(i)+'clip'] = video_photo_clip(video=locals()['anchor_music_t'+str(i)],layer=3,scale_x=0,scale_y=0,
+                   location_x=0,location_y=0,position=time_, end=locals()['anchor_music_t'+str(i)].info.duration,ck=ck_anchor,audio=True)
+        t1.AddClip(locals()['anchor_music_t'+str(i)+'clip'])
+        locals()['anchor_music_t'+str(i)].Close()
+        time_+=locals()['anchor_music_t'+str(i)].info.duration
+        
+    
+    w = video_writer_init("input_self/AI_girl/%s.mp4"%('anchor_music_t'))
+    w.Open()
+    frames = int(t1.info.fps)*int(time_)
+    for n in range(frames):
+        
+        f=t1.GetFrame(n)
+        w.WriteFrame(f)
+    w.Close()
+    t1.Close()
+
+    fname=mp3_to_anchor("input_self/AI_girl/%s.mp4"%('anchor_music_t'))
+    # print(fname)
+    time.sleep(300)
+    while True:
+        result = download_mp4(fname)
+        if result:
+            break
+        print('等待...')
+        time.sleep(60)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    ck=cKey(0,255,0,320)
+    ck_anchor=None
+    #時間
+    time_= 0
+    
+    csv_use=pd.read_csv("input/"+read_csv_use)
+    csv_use=csv_use.dropna(how='all')
+    csv_use.reset_index(inplace=True)
+
+
+
+    anchor_op = openshot.FFmpegReader(op)
+    anchor_op.Open()
+    anchor_clip_op = video_photo_clip(video=anchor_op,layer=2,scale_x=1,scale_y=1,
+            location_x=0,location_y=0,position=time_, end=anchor_op.info.duration,ck=ck_anchor,audio=True)
+    
+    t.AddClip(anchor_clip_op)
+    anchor_op.Close()
+    time_+=anchor_op.info.duration
+
+    start_time = time_
+    locals()['anchor_ad'] = openshot.FFmpegReader('input_self/AI_girl/ai_spokesgirl.mp4')
+    locals()['anchor_ad'].Open()
+    locals()['anchor_clip_ad'] = video_photo_clip(video=locals()['anchor_ad'],layer=6,scale_x=0.8,scale_y=0.8,
+       location_x=0.38,location_y=0.35,position=time_, end=locals()['anchor_ad'].info.duration,ck=ck,audio=False)
+    t.AddClip(locals()['anchor_clip_ad'])
+    locals()['anchor_ad'].Close()
+
+
+
+
+
+
+    for i in range(len(csv_use)):
+    # for i in range(3):
+        pwd_=str(csv_use.loc[i,['音檔']].values[0])
+        layer_choose = 4
+        
+        locals()['anchor_music'+str(i)] = openshot.FFmpegReader("input/"+pwd_use+pwd_)
+        locals()['anchor_music'+str(i)].Open()
+        locals()['anchor_music'+str(i)+'clip'] = video_photo_clip(video=locals()['anchor_music'+str(i)],layer=3,scale_x=0,scale_y=0,
+                   location_x=0,location_y=0,position=time_, end=locals()['anchor_music'+str(i)].info.duration,ck=ck_anchor,audio=True)
+        t.AddClip(locals()['anchor_music'+str(i)+'clip'])
+        locals()['anchor_music'+str(i)].Close()
+
+        if str(csv_use.loc[i,['是否要場景']].values[0])=="是":
+            scale_x_use = 0.59
+            scale_y_use = 0.59
+            
+
+        else:
+            scale_x_use = 1
+            scale_y_use = 1
+            layer_choose =  7
+        choose=str(csv_use.loc[i,['素材']].values[0]).split(".")[-1]
+        pwd_p1=str(csv_use.loc[i,['素材']].values[0])
+
+
+
+
+        if choose == 'mp4':
+            locals()['anchor'+str(i)] = openshot.FFmpegReader("input/"+pwd_use+pwd_p1)
+            locals()['anchor'+str(i)].Open()
+            locals()['anchor'+str(i)+'clip'] = video_photo_clip(video=locals()['anchor'+str(i)],layer=layer_choose,scale_x=scale_x_use,scale_y=scale_y_use,
+               location_x=-0.04,location_y=-0.04,position=time_, end=locals()['anchor_music'+str(i)].info.duration,ck=ck_anchor,audio=False)
+        
+            t.AddClip(locals()['anchor'+str(i)+'clip'])
+            locals()['anchor'+str(i)].Close()
+
+            # if str(csv_use.loc[i,['是否要場景']].values[0])=="是":
+                
+
+            #     locals()['anchor_bg'+str(i)] = openshot.FFmpegReader(bg)
+            #     locals()['anchor_bg'+str(i)].Open()
+            #     locals()['anchor_clip_bg'+str(i)] = video_photo_clip(video=locals()['anchor_bg'+str(i)],layer=2,scale_x=1,scale_y=1,
+            #        location_x=0,location_y=0,position=time_, end=locals()['anchor_music'+str(i)].info.duration,ck=ck,audio=False)
+            #     t.AddClip(locals()['anchor_clip_bg'+str(i)])
+            #     locals()['anchor_bg'+str(i)].Close()
+         
+
+        elif choose == 'jpg' or choose == 'png':
+            locals()['anchor'+str(i)] = openshot.QtImageReader("input/"+pwd_use+pwd_p1)
+            locals()['anchor'+str(i)].Open()
+            locals()['anchor'+str(i)+'clip'] = video_photo_clip(video=locals()['anchor'+str(i)],layer=layer_choose,scale_x=scale_x_use,scale_y=scale_y_use,
+               location_x=-0.04,location_y=-0.04,position=time_, end=locals()['anchor_music'+str(i)].info.duration,ck=ck_anchor,audio=False)
+            t.AddClip(locals()['anchor'+str(i)+'clip'])
+            locals()['anchor'+str(i)].Close()
+            # if str(csv_use.loc[i,['是否要場景']].values[0])=="是":
+
+
+            #     locals()['anchor_bg'+str(i)] = openshot.FFmpegReader(bg)
+            #     locals()['anchor_bg'+str(i)].Open()
+            #     locals()['anchor_clip_bg'+str(i)] = video_photo_clip(video=locals()['anchor_bg'+str(i)],layer=2,scale_x=1,scale_y=1,
+            #        location_x=0,location_y=0,position=time_, end=locals()['anchor_music'+str(i)].info.duration,ck=ck,audio=False)
+            #     t.AddClip(locals()['anchor_clip_bg'+str(i)])
+            #     locals()['anchor_bg'+str(i)].Close()
+
+        time_+=locals()['anchor_music'+str(i)].info.duration
+
+    locals()['anchor_bg'] = openshot.FFmpegReader(bg)
+    locals()['anchor_bg'].Open()
+    locals()['anchor_clip_bg'] = video_photo_clip(video=locals()['anchor_bg'],layer=2,scale_x=1,scale_y=1,
+       location_x=0,location_y=0,position=start_time, end=time_-start_time,ck=ck,audio=False)
+    t.AddClip(locals()['anchor_clip_bg'])
+    locals()['anchor_bg'].Close()
+
+
+
+
+            
+ 
+    
+
+    
+
+
+    anchor_ed = openshot.FFmpegReader(ed)
+    anchor_ed.Open()
+    anchor_clip_ed = video_photo_clip(video=anchor_ed,layer=2,scale_x=1,scale_y=1,
+            location_x=0,location_y=0,position=time_, end=anchor_ed.info.duration,ck=ck_anchor,audio=True)
+    time_+=anchor_ed.info.duration
+    t.AddClip(anchor_clip_ed)
+    anchor_ed.Close()
+
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+    
+    w = video_writer_init("input_self/tmp1/test.mp4")
+    w.Open()
+    
+    frames = int(t.info.fps)*int(time_)
+    for n in range(frames):
+        f=t.GetFrame(n)
+        w.WriteFrame(f)
+
+    t.Close()
+    w.Close()
+    shutil.rmtree('input')
+    os.mkdir('input')
+    shutil.rmtree('input_self/AI_girl')
+    os.mkdir('input_self/AI_girl')
+#文字轉圖片
+def txt2image(content, save_target,lang='zh',size=26,fon="input_self/font/DFT_B7.ttc"):
+    unicode_text = trim_punctuation(content)
+    font = ''
+    if lang=='zh':
+        font = ImageFont.truetype(font=fon, size=size)
+    else :
+        font = ImageFont.truetype(font="input_self/font/arial.ttf", size=size)
+    
+    W, H = (1280,500)
+    canvas = Image.new('RGB', (W, H), "#00FF00")
+    draw = ImageDraw.Draw(canvas)
+    
+    text= content
+    if "\n" in text:
+        w, h = draw.textsize(text.split("\n")[0],font = font)
+        #draw.text(((W-w)/2,0), text[0:18],'black', font)
+        text_border(draw,(W-w)/2,0,text.split("\n")[0],font,'black','white')
+        w, h = draw.textsize(text.split("\n")[1],font = font)
+        #draw.text(((W-w)/2,h+2), text[18:],'black', font)
+        text_border(draw,(W-w)/2,h+2,text.split("\n")[1],font,'black','white')
+    else:
+        w, h = draw.textsize(content,font = font)
+        #draw.text(((W-w)/2,0), text,'black', font)
+        text_border(draw,(W-w)/2,0,text,font,'black','white')
+    canvas.save(save_target, "PNG")
+
+def text_border(draw,x,y,text,font,shadowcolor,fillcolor):
+    draw.text((x-1, y), text, font=font, fill=shadowcolor)
+    draw.text((x+1, y), text, font=font, fill=shadowcolor)
+    draw.text((x, y-1), text, font=font, fill=shadowcolor)
+    draw.text((x, y+1), text, font=font, fill=shadowcolor)
+
+    draw.text((x-1, y+1), text, font=font, fill=shadowcolor)
+    draw.text((x+1, y-1), text, font=font, fill=shadowcolor)
+    draw.text((x-1, y-1), text, font=font, fill=shadowcolor)
+    draw.text((x+1, y+1), text, font=font, fill=shadowcolor)
+    # thicker border
+    draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
+    draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
+    draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
+    draw.text((x+2, y+2), text, font=font, fill=shadowcolor)
+
+    # now draw the text over it
+    draw.text((x, y), text, font=font, fill=fillcolor)
+
+def srt_to_csv(srt_file):
+    subs = pysrt.open(srt_file)
+    csv_file = srt_file.split('.')[0] + ".csv"
+    with open(csv_file, 'w', newline='') as csvfile:
+        # 建立 CSV 檔寫入器
+        writer = csv.writer(csvfile)
+        for context in subs:
+            writer.writerow([context.index, context.start,context.end, context.text])
+    return csv_file
+
+def csv_to_text(csv_file,text_font):
+    text_form = []
+    with open(csv_file, newline='') as csvfile:
+
+        # 讀取 CSV 檔案內容
+        rows = csv.reader(csvfile)
+
+        # 以迴圈輸出每一列
+        for row in rows:
+            start = datetime.strptime(row[1], "%H:%M:%S,%f")
+            end = datetime.strptime(row[2], "%H:%M:%S,%f") - datetime.strptime(row[1], "%H:%M:%S,%f")
+            end_timeStamp=end.seconds+0.000001*end.microseconds
+            start_timeStamp=start.minute*60+start.second+ 0.000001*start.microsecond
+            text_form.append({'text':row[3],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
+    
+    return text_form
+def text_to_short_vedio(mp4_file ,sound_file,output_filename,text_font):
+    t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
+    t.Open()
+    
+    # 去背參數
+    ck = cKey(0, 254, 0, 270)
+    ck_anchor = cKey(0, 255, 0, 320)
+
+    anchor = openshot.FFmpegReader(mp4_file)
+    anchor.Open()
+    anchor_clip = video_photo_clip(video=anchor,layer=2,scale_x=1,scale_y=1,
+            location_x=0,location_y=0,position=0, end=anchor.info.duration,audio=True)
+    t.AddClip(anchor_clip)
+    anchor.Close()
+    number = 0
+
+    sound_srt_file = ""
+    #音檔自動產生srt(逐字稿)
+    if ".srt" in sound_file:
+        sound_srt_file = sound_file
+    elif not sound_file is None:
+        cmd = "autosub -S zh-TW -D zh-TW " + sound_file
+        os.system(cmd)
+        sound_srt_file = sound_file.split('.')[0] + ".srt"
+    csv_file = srt_to_csv(sound_srt_file)
+    text_form = csv_to_text(csv_file,text_font)
+    print(sound_srt_file)
+    #開啟srt檔
+    try:
+        # subs = pysrt.open(sound_srt_file)
+        # text_form = []
+        # for context in subs:
+        #     #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
+        #     end = context.end-context.start
+        #     end_timeStamp=(end.minutes*60+end.seconds+ 0.001*end.milliseconds)
+        #     start_timeStamp=(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
+        #     text_form.append({'text':context.text,'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
+        number = 0
+        for text_tmp in text_form:
+            file_name = "input_self/tmp/save_target_" + str(number) + ".png"
+            txt2image(text_tmp['text'], file_name,lang='zh',size = text_tmp['size'],fon = text_tmp['font'])
+            exec('text_anchor_{} = openshot.QtImageReader("input_self/tmp/save_target_{}.png")'.format(number,number))
+            exec('text_anchor_{}.Open()'.format(number))
+            exec('text_anchor_{}.Open()'.format(number))
+            exec('text_anchor_clip_{} = video_photo_clip(video=text_anchor_{},layer=4,scale_x=1,scale_y=1,\
+                    location_x=0,location_y=0.67,position=text_tmp["start"], end=text_tmp["end"],ck=ck_anchor,audio=True)'.format(number,number))
+            exec('t.AddClip(text_anchor_clip_{})'.format(number))
+            exec('text_anchor_{}.Close()'.format(number))
+            number = number+1
+    except:
+        print("無法開啟srt檔案(字幕產生失敗)")
+
+    w = video_writer_init(output_filename)
+    w.Open()
+
+    frames = int(t.info.fps)*int(anchor.info.duration)
+    for n in range(frames):
+        f=t.GetFrame(n)
+        w.WriteFrame(f)
+
+    t.Close()
+    w.Close()
+
+    #刪除暫存檔案
+    shutil.rmtree('input_self/tmp')
+    os.mkdir('input_self/tmp')
+    shutil.rmtree('input_self/tmp1')
+    os.mkdir('input_self/tmp1')
+
+
+if __name__ == '__main__':
+	# text_to_short_vedio_create()
+	text_to_short_vedio(mp4_file = "input_self/tmp1/test.mp4",sound_file ='input_self/tmp1/test.mp4',
+        output_filename="output/demo.mp4",text_font ="input_self/font/DFT_R7.ttc")

+ 11 - 0
AI_anchor2/readme.md

@@ -0,0 +1,11 @@
+1. docker建立
+	(1)build和run
+		docker  build -t [想取tag名稱] .
+		docker run -it -v [本地資料夾]:[docker資料夾] [想取tag名稱]
+		
+	EX:
+		docker build -t ai_anchor .
+		docker run -it -v C:/Users/oak/Desktop/AI_anchor:/app ai_anchor
+		
+2.使用說明:(檔案名稱沒有限制,但格式請參考圖1~圖7說明和sample_explain.csv說明)
+	

+ 44 - 0
AI_anchor2/sample.csv

@@ -0,0 +1,44 @@
+字幕,素材,音檔,是否要場景
+"各位觀看影片的觀眾大家好。
+導盲犬,就如同黑夜中的亮光,為社會上的視障朋友指引生命方向。我是公益頻道AI主持人Peggy。在社會上不管是天生,或是後天影響,視障朋友在生活上會遇到很多困難。",C0048.mp4,開場v2_1.mp4,是
+而這時,導盲犬身為視障朋友的另一雙眼睛,需要導盲犬的努力工作,才能引導視障者安全的抵達目的地。本次我們也邀請到了台灣導盲犬協會的導盲犬訓練師以及視障朋友來接受我們的專訪,讓他們來為各位講解及分享有關於導盲犬的故事。,DSC00167.jpg,開場v2_2.mp4,是
+"台灣導盲犬協會成立於2002年,至今也成立很長一段時間了,在社會上的知名度也很高,並且對於導盲犬協會的工作內容相信大眾也有一定的了解。
+一定也有很多人會問說我家的狗狗可不可以當導盲犬?在導盲犬的犬種類型上可以簡單為我們介紹導盲犬的品種,或是怎麼樣的狗狗才能夠當導盲犬呢?
+而又在訓練途中,一隻狗狗需要經過多久的時間訓練成為導盲犬?會不會跟人一樣會有遇到要退休的問題呢?",DSC00157.jpg,Q1_new.mp3,是
+,,,
+"導盲犬有一個很重要的特性就是他,需要非常足夠的穩定性
+然後台灣比較常見的導盲犬品種有拉不拉多跟黃金獵犬
+可是黃金拉拉,因為他們的說他祖宗們
+他的祖先啊他的爸爸媽媽,全部都是導盲犬他才有機會可以成為導盲犬喔",ChoozMo 公益頻道專訪-導盲犬協會v2_Q1_11.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q1_11.mp4,否
+"一出生孩子兩個月大左右開始做訓練,那訓練期大概是訓練到兩歲到3歲做
+那他們退休的年齡,大概會在他
+退休之後會找適合他的收養家庭",C0050.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q1_12.mp4,否
+在這個過程中,通過寄養家庭的生活,要如何引導訓練導盲犬?讓視障者跟導盲犬能夠成功媒合一起工作?,2022_04_15_163616.jpg,Q3.mp3,是
+,,,
+"剛講要導盲犬的訓練起來他們從兩個月大,他們兩個月大到1歲左右會在寄養家庭那邊學習導盲犬社會化訓練
+學習什麼進入人類的社會,怎麼搭電梯搭手扶梯要怎麼在公車上捷運上好好的待著
+哪間餐廳的話要遵守什麼樣的禮貌禮節,這個是他們在寄養家庭時期訓練部份
+大概到他1歲到1歲半左右會進來協會來做正式的訓練,領導訓練就是學習怎麼帶著人走路、閃避障礙物
+怎麼知道左轉右轉,他們在引導訓練的時期說要學習
+那這段時間大概會訓練到牠2歲到3歲,他畢業了之後,就會安排適合他",ChoozMo 公益頻道專訪-導盲犬協會v2_Q2_1.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q2_1.mp4,否
+"他的視障朋友來跟他做媒合來做配對,他們會經過一個月到三個月不等
+等等同步訓練,然後訓練完成之後他們才會正式開始一起工作
+那工作完成他們還會在他們適合的退休年齡",C0049.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q2_2.mp4,否
+"對於視障者來說,導盲犬是生活中一個非常重要的夥伴。
+為了不中斷導盲犬的培訓,如果社會大眾想要來幫助導盲犬的生活、協助台灣導盲犬協會,請問有甚麼方法能夠讓大家出一份力呢?",2022_04_15_165219.jpg,Q7.mp3,是
+,,,
+"我們培訓導盲犬來服務視障朋友那視障朋友來申請導盲犬是完全免費的
+那我們的資金來源都來自民眾的募款,民眾來幫我們、認購我們的義賣商品
+義賣商品有很多種,像是我們最近有新推出的T-shirt啊、帽子還有馬克杯等等
+都可以來做餐飲,那我們也同時有在招募寄養家庭
+如果你們家合適的話也可以,申請我們的寄養家庭",ChoozMo 公益頻道專訪-導盲犬協會v2_Q3.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q3.mp4,否
+,,,
+台灣導盲犬在今年2022年、協會20周年,而四月也是國際導盲犬月。,277571724_10166131245740023_6217328854393384830_n.jpg,Q8_1.mp4,是
+請問在近期有沒有甚麼要推廣的活動,或是要跟社會大眾一起分享的事情呢?,277529793_10166131246365023_3628722343253840018_n.jpg,Q8_2.mp4,是
+我們台灣導盲犬協會帶週末不定期會有義賣活動,義賣宣導活動,ChoozMo 公益頻道專訪-導盲犬協會v2_Q4_1.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q4_1.mp4,否
+也歡迎大家可以來我們的臉書上看我們的活動資訊,導盲犬協會FB.jpg,ChoozMo 公益頻道專訪-導盲犬協會v2_Q4_2.mp4,否
+那如果有興趣從我們的活動義工的話留言給我們,或是寫email來給我們,ChoozMo 公益頻道專訪-導盲犬協會v2_Q4_3.mp4,ChoozMo 公益頻道專訪-導盲犬協會v2_Q4_3.mp4,否
+"好的,謝謝今天台灣導盲犬協會的魏訓練師接受我們的專訪。
+讓我們更了解到導盲犬對於視障朋友生活上的幫助。對於他們來說,導盲犬的意義不僅止於工作夥伴,",276028589_10166102370890023_6142788518415928968_n.jpg,結語_11.mp4,是
+"反而更像是能帶給他們陪伴、安全感的家人,再一次感謝台灣導盲犬協會能夠安排讓我們專訪,
+希望在四月的國際導盲犬月上能夠讓社會大眾更加認識到導盲犬、對協會有更好的幫助。",275137212_10166066186845023_1707459651545440166_n.jpg,結語_22.mp4,是

+ 22 - 0
AI_anchor2/sample_explain.csv

@@ -0,0 +1,22 @@
+字幕,素材,音檔,是否要場景
+通常為這段片段呈現字幕內容,"呈現在畫面上樣子(不包含其聲音)(可能是圖片或是影片),如果是圖片則維持和音檔相同長度的畫面時間,如果是影音檔則會播放影片直到音檔聲音結束",呈現在畫面上樣子(不包含其畫面)主要為這支影片聲音,這段是否要有AI主播場景
+EX:,,,
+字幕1,影片1.mp4,聲音1.mp3,是
+字幕2,影片2.jpg,聲音2.mp4,是
+字幕3,影片3.png,聲音3.mp3,否
+⋮,,,
+,素材請使用.mp4/.jpg/.png(小寫),"音檔沒有特別限制,但盡量使用.mp4/.mp3",請使用 是/否
+,,,
+,,,
+備註:詳細可以參考sample.csv寫法,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,
+,,,