「Youtube字幕の色が自動で変わるように、投稿者側で色を設定する。」のソースコード

#初めに
本記事は以下の記事のソースコードです。
>[Youtube字幕の色が自動で変わるように、投稿者側で色を設定する。](https://qiita.com/wy0727_betch/items/6e3d42e79e172ef637e3)

編集が可能な方は自由に使ってください。

#注意点

- もともと公開するつもりはあまりなかったので、解読性はかなり悪いです。一応コメントはつけていますが、ほとんど参考にならないかも。
- プログラミング自体素人なもので、書き方を間違えてるところがあるかもしれないです。（一応動くとは思いますが）
- 使い方等は上記記事で書いています。興味がありましたら見ていただけると嬉しいです。
- もし改善点等ありましたら、コメントしていただけたら嬉しいです。

#ソースコード
動作には設定ファイル等が必要なので、上記の記事からダウンロードしてください。
簡単に言うと、Youtubeからダウンロードできる字幕ファイルをカラーコードが記述できる形式に変換し、指定したカラーコードを追加していく感じです。
Youtubeからダウンロードした字幕ファイルと変換後のファイルでの時間の単位が違うため、前半部分でごちゃごちゃやってます。
「＋」を大量に使ってますが、今考えれば「.format()」つかえばよかったなーと

```色付き字幕作成ツール.py
# -*- coding: utf-8 -*-
import os
import zipfile
import sys
from time import sleep

SetRoot = "./設定ファイル/"
CapRoot = "./ダウンロードした字幕ファイルはこの中に入れてください。/"

#---定義ファイルをもとにカラーコード辞書型作成------------------------------------------------------------
ReadLineNum = 0
try:
    with open(SetRoot + "使用する色と指定文字.txt",'r',encoding="utf-8") as d:
        ColorCode = [s.strip() for s in d.readlines()]
except FileNotFoundError:
    print("「使用する色と指定文字.txt」ファイルが存在しません。作成するかもう一度ダウンロードしてください。")
    print("Enterキーで終了します。")
    k = input()
    sys.exit()
ColorCodeLineEnd = len(ColorCode) - 1
ColorCodeDic = {str(ColorCode[ReadLineNum].split(":")[0]):str(ColorCode[ReadLineNum].split(":")[1])}
while True:
    if ColorCodeLineEnd == ReadLineNum:
        break
    else:
        ReadLineNum += 1
        ColorCodeDic.update({str(ColorCode[ReadLineNum].split(":")[0]):str(ColorCode[ReadLineNum].split(":")[1])})
#-----------------------------------------------------------------------------------------------------

#---Captionsファイルをリスト型に、タイムコードをミリ秒に変換後、RawCodeとしてリスト型で保存------------------
try:
    with open(CapRoot + "captions.sbv",'r',encoding="utf-8") as f:
        Captions = [s.strip() for s in f.readlines()]
        FileType = 1
except FileNotFoundError:
    try:
        with open(CapRoot + "captions.srt",'r',encoding="utf_8_sig") as f:
            Captions = [s.strip() for s in f.readlines()]
            FileType = 2
    except FileNotFoundError:
        print("「captions.sbv」または「captions.srt」ファイルが存在しません。ファイル形式・名前があっているか確認してください。")
        print("Enterキーで終了します。")
        k = input()
        sys.exit()
CaptionsLineEnd = len(Captions) - 1
ReadLineNum = 0
RawCode = ["Code"]

if FileType == 1:
    while True:
        if Captions[ReadLineNum][1:2] == ":" and Captions[ReadLineNum][13:14] == ":":
            start = Captions[ReadLineNum][0:11].split(":")
            a = start[2].split(".")
            start = int(start[0]) * 3600000 + int(start[1]) * 60000 + int(a[0]) * 1000 + int(a[1])
            RawCode.append(str(start))
            end = Captions[ReadLineNum][12:23].split(":")
            a = end[2].split(".")
            end = int(end[0]) * 3600000 + int(end[1]) * 60000 + int(a[0]) * 1000 + int(a[1])
            RawCode.append(str(end))
        elif Captions[ReadLineNum] == "":
            pass
        else:
            RawCode.append(Captions[ReadLineNum])
        if ReadLineNum == CaptionsLineEnd:
            break
        else:
            ReadLineNum += 1

elif FileType == 2:
    while True:
        if Captions[ReadLineNum].isnumeric() == True:
            ReadLineNum += 1
            start = Captions[ReadLineNum][0:12].split(":")
            a = start[2].split(",")
            start = int(start[0]) * 3600000 + int(start[1]) * 60000 + int(a[0]) * 1000 + int(a[1])
            RawCode.append(str(start))
            end = Captions[ReadLineNum][17:29].split(":")
            a = end[2].split(",")
            end = int(end[0]) * 3600000 + int(end[1]) * 60000 + int(a[0]) * 1000 + int(a[1])
            RawCode.append(str(end))
        elif Captions[ReadLineNum] == "":
            pass
        else:
            RawCode.append(Captions[ReadLineNum])
        if ReadLineNum == CaptionsLineEnd:
            break
        else:
            ReadLineNum += 1

#-----------------------------------------------------------------------------------------------------

#---RawCodeを成形し直し、EditCodeとしてリスト型で保存----------------------------------------------------
RawCodeLineEnd = len(RawCode) - 1
ReadLineNum = 1
EditCode = ["EditCode"]
Break = 0
CountSentence = 0

while True:
    EditCode.append(RawCode[ReadLineNum])
    ReadLineNum += 1
    end = RawCode[ReadLineNum]
    ReadLineNum += 1
    word = RawCode[ReadLineNum]
    while True:
        if ReadLineNum == RawCodeLineEnd:
            EditCode.append(word)
            CountSentence += 1
            Break = 1
            break
        if RawCode[ReadLineNum].isnumeric() == False and RawCode[ReadLineNum + 1].isnumeric() == False: # 字幕に改行がある場合、改行コードも含めて追加
            word = word  + "</b><br><b>" + RawCode[ReadLineNum + 1]
            ReadLineNum += 1
        else:
            EditCode.append(word)
            CountSentence += 1
            break
    if Break == 1:
        break
    ReadLineNum += 1
    if RawCode[ReadLineNum] == end:
        pass
    else:                         # 表示する字幕の開始時間とそのひとつ前の字幕の終了時間が一致しない場合
        EditCode.append(end)      # ひとつ前の字幕の終了時間から表示する文字列を作り
        EditCode.append("&nbsp;") # 表示しないことを表す文字列を代入

#-----------------------------------------------------------------------------------------------------

#---色指定ファイルをもとに、各字幕の色情報のリストを作成--------------------------------------------------
try:
    with open(SetRoot + "色指定ファイル.txt",'r',encoding="utf-8") as n:
        ColorCodeRaw = [s.strip() for s in n.readlines()]
except FileNotFoundError:
    print("「色指定ファイル.txt」ファイルが存在しません。作成するかもう一度ダウンロードしてください。")
    print("Enterキーで終了します。")
    k = input()
    sys.exit()
ColorCodeLineMax = len(ColorCodeRaw) - 1
ReadLineNum = 0
ColorCode = ["ColorCode"]

if ColorCodeRaw[0][0:3] == "all":
    AllSameColor = 1
else:
    AllSameColor = 0

while True:
    if ReadLineNum < CountSentence:
        if AllSameColor == 1:
            ColorCode.append(str(ColorCodeRaw[0].split(" ")[1]))
        elif ColorCodeLineMax < ReadLineNum:
            ColorCode.append(str(ColorCodeRaw[ColorCodeLineMax]))
        else:
            ColorCode.append(str(ColorCodeRaw[ReadLineNum]))
        ReadLineNum += 1
    elif ReadLineNum == CountSentence:
        break

#-----------------------------------------------------------------------------------------------------

#---入力を求める---------------------------------------------------------------------------------------
FileNameDic = {"1":"captions.sbv","2":"captions.srt"}

print("読み込んだ字幕ファイル : " + FileNameDic[str(FileType)])
print("使用可能な色 : " + str(ColorCodeLineEnd + 1) + "色")
if AllSameColor == 1:
    w = "同一色（" + ColorCodeDic[ColorCode[1]] + "）\n"
else:
    w = "文章によって変更する\n"
print("色指定モード : " + w)
print("必要なファイルの読み込みが完了しました。これより字幕ファイルの作成を行います。")
print("上記読み込み内容に間違いがないか確認し、作成を開始する場合は「y]、やめる場合は「n」を入力後、Enterを押してください。")
key = input()
if key == "y":
    print("作成したデータを保存するファイルの名前を入力してください。拡張子は不要です。(入力後Enterキーを押してください)")
    FileName = input()
    if FileName == "":
        print("入力されなかったため、「ColorSubtitles.smi」として保存します。")
        FileName = "ColorSubtitles.smi"
    else:
        print("「" + FileName + ".smi」として保存します。")
        FileName = FileName + ".smi"
    print("Enterキーで作業を開始します。")
    k = input()
else:
    print("作業を中止しました。Enterキーで終了します。")
    k = input()
    sys.exit()

#-----------------------------------------------------------------------------------------------------

#---EditCodeをもとにファイルにおこす-----------------------------------------------------------------------

SentenceLineEnd = len(EditCode) - 1
ReadLineNum = 1
Sentence = ["<SAMI>\n<HEAD>\n<SAMIParam>\nMetrics {time:ms;}\nSpec {MSFT:1.0;}\n</SAMIParam>\n</HEAD>\n<BODY>\n"]
SentenceNum = 1

while True:
    Sentence.append('<SYNC Start=' + str(EditCode[ReadLineNum]) + '>')
    print('<SYNC Start=' + str(EditCode[ReadLineNum]) + '>')
    ReadLineNum += 1
    if EditCode[ReadLineNum] == "&nbsp;":
        Sentence.append('&nbsp;\n')
        print('&nbsp;')
    else:
        Sentence.append('<font color="' + ColorCodeDic[ColorCode[SentenceNum]] + '"><b>' + str(EditCode[ReadLineNum]) + '</b></font>\n')
        print('<font color="' + ColorCodeDic[ColorCode[SentenceNum]] + '"><b>' + str(EditCode[ReadLineNum]) + '</b></font>')
        SentenceNum += 1
    if ReadLineNum == SentenceLineEnd:
        break
    else:
        ReadLineNum += 1
    sleep(0.01)
with open("./" + FileName, mode='a',encoding="utf-8") as f:
    f.writelines(Sentence)

#-----------------------------------------------------------------------------------------------------

print("\n\n書き出し作業が完了しました。「" + FileName  + "」として保存しました。")
print("Enterキーで終了します。")
k = input()
sys.exit()
```

#太文字について
すべての字幕が太文字になる設定になっています。変更したい場合は、スクリプト下部「EditCodeをもとにファイルにおこす」の段で、\<b>と\</b>のタグを削除してください。
該当部分に下記抜粋をコピペしてもいいです。

スクリプトの下部抜粋

```色付き字幕作成ツール.py
#---EditCodeをもとにファイルにおこす-----------------------------------------------------------------------

SentenceLineEnd = len(EditCode) - 1
ReadLineNum = 1
Sentence = ["<SAMI>\n<HEAD>\n<SAMIParam>\nMetrics {time:ms;}\nSpec {MSFT:1.0;}\n</SAMIParam>\n</HEAD>\n<BODY>\n"]
SentenceNum = 1

while True:
    Sentence.append('<SYNC Start=' + str(EditCode[ReadLineNum]) + '>')
    print('<SYNC Start=' + str(EditCode[ReadLineNum]) + '>')
    ReadLineNum += 1
    if EditCode[ReadLineNum] == "&nbsp;":
        Sentence.append('&nbsp;\n')
        print('&nbsp;')
    else:
        Sentence.append('<font color="' + ColorCodeDic[ColorCode[SentenceNum]] + '">' + str(EditCode[ReadLineNum]) + '</font>\n')
        print('<font color="' + ColorCodeDic[ColorCode[SentenceNum]] + '">' + str(EditCode[ReadLineNum]) + '</font>')
        SentenceNum += 1
    if ReadLineNum == SentenceLineEnd:
        break
    else:
        ReadLineNum += 1
    sleep(0.01)
with open("./" + FileName, mode='a',encoding="utf-8") as f:
    f.writelines(Sentence)

#-----------------------------------------------------------------------------------------------------

print("\n\n書き出し作業が完了しました。「" + FileName  + "」として保存しました。")
print("Enterキーで終了します。")
k = input()
sys.exit()
```
タグの部分を書き換えれば、違ったように表示されることもできます。
（bのタグ、uのタグはそれぞれ太字、下線）
表示させる字幕すべてに適応されてしまいますが・・・
情報をくれた方ありがとうございます。

#exe化について
exe化には以下の記事を参考にしました。
>[Pythonのファイルをexe化する方法【初心者向け】](https://techacademy.jp/magazine/18963)