テキストレイヤーを別の言語に置き換えたいときなど 言語によってはCSVが上手くいかないかも

コンポジションにあらかじめテロップ用のレイヤーを作成する TEXT1、TEXT2 など

ベースのテロップを並べ終わって、コンポジションを選択した状態で下記を実行

ny_TelopTranslateFromCsv_prepare.jsx

// 選択しているコンポジションのレイヤー名を取得し、aepファイルと同じディレクトリにCSVファイルを生成するスクリプト

(function () {
    function getLayerNamesFromComp(comp) {
        var layerNames = [];
        for (var i = 1; i <= comp.numLayers; i++) {
            layerNames.push(comp.layer(i).name);
        }
        //ヘッダー行追加
        layerNames.push("BaseTelop");

        // layerNamesの順番を逆にする
        layerNames.reverse();
        return layerNames;
    }

    function saveToFile(layerNames, filePath) {
        var file = new File(filePath);
        if (file.open("w")) {
            file.write(layerNames.join("\n"));
            file.close();
            // 出力ファイルを開く場合
            file.execute();
            return true;
        } else {
            return false;
        }
    }

    // スクリプトのメイン処理
    app.beginUndoGroup("Save Layer Names to File");

    var activeItem = app.project.activeItem;

    if (activeItem && activeItem instanceof CompItem) {
        var layerNames = getLayerNamesFromComp(activeItem);
        if (layerNames.length > 0) {
            var projectFile = app.project.file; // 現在のプロジェクトファイル (.aep)
            if (projectFile) {
                var projectPath = projectFile.path; // .aepファイルのディレクトリ
                var textFilePath = projectPath + "/" + "TelopTranslate_BaseTelopLayerNames.csv";

                if (saveToFile(layerNames, textFilePath)) {
                    alert("レイヤー名が以下のファイルに保存されました:\n" + textFilePath);
                } else {
                    alert("ファイルの保存に失敗しました。");
                }
            } else {
                alert("プロジェクトファイルが保存されていません。プロジェクトを保存してください。");
            }
        } else {
            alert("選択したコンポジションにレイヤーがありません。");
        }
    } else {
        alert("コンポジションを選択してください。");
    }

    app.endUndoGroup();
})();

TelopTranslate_BaseTelopLayerNames.csv

BaseTelop
命果てるもの
海馬を横切る鼓動
永遠がそこにあるなら
終わりは何故怖いの
花の香りよ
煙る時雨柔らかい熱は
解けて冷たく沈む自我に命は燃えている
かたちの無いもの
それに囚われるもの
歪に揺れる蜃気楼
吸い込まれてしまいそう
何故悲しいの
どうして泣いているの
脳裏をよぎるテレパシー
死ぬ間際にわかるなら何?

TelopTranslate_BaseTelopLayerNames.csv を編集して 変換用のCSVを作成する

下記のようなCSVファイルを作成する

TelopTranslate.csv

BaseTelop,Telop,TextLayer
命果てるもの,生命的终结,TEXT2
海馬を横切る鼓動,心跳穿过海马体,TEXT2
永遠がそこにあるなら,如果永恒就在那里,TEXT2
終わりは何故怖いの,你为何害怕结束?,TEXT2
花の香りよ,花的芬芳,TEXT2
煙る時雨柔らかい熱は,烟雨柔热,TEXT2
解けて冷たく沈む自我に命は燃えている,生命在融化和冰冷的自我中燃烧,TEXT2
かたちの無いもの,无形之物,TEXT2
それに囚われるもの,陷入其中,TEXT2
歪に揺れる蜃気楼,扭曲闪烁的海市蜃楼,TEXT2
吸い込まれてしまいそう,我感觉自己被吸了进去,TEXT2
何故悲しいの,你为何悲伤?,TEXT2
どうして泣いているの,你为什么哭泣?,TEXT2
脳裏をよぎるテレパシー,我脑海中的心灵感应,TEXT2
死ぬ間際にわかるなら何?,如果你快死了,你会知道什么?,TEXT2

下記を実行してTelopTranslate.csvを選択する

ny_TelopTranslateFromCsv.jsx

(function () {
    // 現在選択しているコンポジションを取得
    var comp = app.project.activeItem;

    // コンポジションが選択されていることを確認
    if (comp && comp instanceof CompItem) {
        app.beginUndoGroup("Create Telop Text Layers");

        // オーディオファイルのレイヤー情報を格納する配列
        var baseTelopData = [];

        // コンポジション内のレイヤーを確認
        for (var i = 1; i <= comp.numLayers; i++) {
            var layer = comp.layer(i);

            // オーディオファイルレイヤーを探し、その情報を配列に格納
            if (layer instanceof TextLayer) {
                baseTelopData.push({
                    name: layer.name,
                    inPoint: layer.inPoint,
                    outPoint: layer.outPoint,
                    index: i  // レイヤーのインデックス
                });
            }
        }

        // ファイル選択ダイアログでCSVファイルを選択
        var csvFile = File.openDialog("CSVファイルを選択してください", "*.csv");

        if (!csvFile) {
            alert("CSVファイルが選択されていません。");
            app.endUndoGroup();
            return;
        }

        var telopData = [];
        csvFile.open("r");

        // ヘッダ行をスキップ
        csvFile.readln();

        // CSVを読み込み、配列に格納
        while (!csvFile.eof) {
            var line = csvFile.readln();
            var columns = line.split(",");
            telopData.push({
                baseTelopLayer: columns[0],
                telop: columns[1],
                textLayer: columns[2]
            });
        }

        csvFile.close();

        // telopDataの順番を逆にする
        telopData.reverse();

        // 新しいレイヤーが既存のインデックスを保ちながら追加されるように設定
        var currentLayerIndex = comp.numLayers;  // 新しいレイヤーを追加するインデックス

        // CSVデータに基づいてテキストレイヤーを複製し、テキストを変更
        for (var j = 0; j < telopData.length; j++) {
            var data = telopData[j];

            // オーディオレイヤーを検索 (findの代わりにforループで手動で検索)
            var baseTelopLayer = null;
            for (var k = 0; k < baseTelopData.length; k++) {
                if (baseTelopData[k].name === data.baseTelopLayer) {
                    baseTelopLayer = baseTelopData[k];
                    break;
                }
            }

            if (!baseTelopLayer) {
                alert("baseTelopLayer '" + data.baseTelopLayer + "' が見つかりません。");
                continue;
            }

            // 対応するテキストレイヤーを探す
            var textLayer = comp.layer(data.textLayer);
            if (!textLayer) {
                alert("テキストレイヤー '" + data.textLayer + "' が見つかりません。");
                continue;
            }

            // テキストレイヤーを複製
            var newTextLayer = textLayer.duplicate();
            newTextLayer.name = data.telop;

            // 複製したテキストレイヤーのインポイントとアウトポイントを設定
            newTextLayer.inPoint = baseTelopLayer.inPoint;
            newTextLayer.outPoint = baseTelopLayer.outPoint;

            // テキストの内容を変更
            newTextLayer.text.sourceText.setValue(data.telop);

            // 新しいレイヤーをコンポジションの一番上に移動
            // newTextLayer.moveToBeginning();
        }

        app.endUndoGroup();
    } else {
        alert("コンポジションを選択してください。");
    }
})();