G-6GNCDT1HSV After Effectsの不明なフッテージを一括で再リンクする方法【2026年版】
After Effects
PR

After Effectsの不明なフッテージを一括で再リンクする方法【2026年版】自作スクリプトのコードつき

kitagawatetsuro
記事内に商品プロモーションを含む場合があります
After Effectsの不明なフッテージを一括で再リンクするスクリプトを紹介するアイキャッチ画像

プロジェクトを開いた瞬間に「○個のファイルが見つかりません」と表示され、コンポジションがカラーバーだらけ……。素材を移動したり別のPCで開いたりすると起きる「不明なフッテージ」は、数が多いと1つずつ直すだけで一仕事です。

🔗 不明なフッテージ
📜 自作スクリプト
🛡️ 安全チェック付き

✅ 結論:同じ名前のファイルを探して一括で再リンクするスクリプトで、手作業を減らせる

不明なフッテージは、「フッテージを置き換え」で1つずつ直すのが基本です。数が多い時は、素材を探すフォルダを指定して、同じファイル名のものを自動で再リンクするスクリプト「リンクオート」を使うと、まとめて直せます。この記事では、自作スクリプトのコード全文と、導入から使い方、注意点までを解説します。

不明な
フッテージとは
手動での
直し方
スクリプトの
導入と使い方
注意点と
できないこと

Premiere Proで同じ状態になった時はPremiere Proで素材が赤い画面(メディアオフライン)になった時の直し方、外注や別PCに渡す時の整理はPremiere Proのプロジェクト整理・引き継ぎ術もあわせてご覧ください。この記事は「After Effectsの不明なフッテージを直す」ことに絞って解説します。

こっこちゃん「素材のフォルダを整理したら、After Effectsのプロジェクトがカラーバーだらけになっちゃいました……」

白い鴉「素材の場所が変わると、プロジェクト側が元の場所を覚えたままで見つけられなくなるんだ。数が少なければ手で直せるけど、数十個あると大変だから、自動で探して直すスクリプトも作ってあるよ」

📋 この記事の要約

After Effectsのプロジェクトは素材そのものを持たず、元のファイルの場所を覚えて参照しています。素材を移動・名前変更・削除したり、別のPCで開いたりすると参照先が見つからなくなり、コンポジションにはカラーバーが表示されます。直し方の基本は、素材を右クリックして「フッテージを置き換え」→「ファイル…」で正しいファイルを選び直すことです。数が多い時は、素材を探すフォルダを指定して同名ファイルを自動で再リンクするスクリプト「リンクオート」が便利です。まず変更せずに結果だけ確認する「安全チェック」ができ、実行結果は一覧のテキストファイルに残せます。

🧩 不明なフッテージとは

After Effectsのプロジェクトファイル(.aep)には、動画や画像の中身そのものは入っていません。「どこにあるファイルを使うか」という場所(パス)だけを覚えていて、開く時にその場所から素材を読み込んでいます。そのため、素材を移動・名前変更・削除したり、別のPCや外付けドライブの文字が変わった環境で開いたりすると、参照先が見つからなくなります。この状態を「不明なフッテージ」と呼び、コンポジションでは素材の代わりにカラーバー(色の縞模様)が表示されます。

After Effectsで素材が見つからずカラーバーになる状態と、再リンク後に素材が表示される状態を比較するインフォグラフィック

🔧 手動での直し方

基本の直し方は、プロジェクトパネルで不明なフッテージを右クリックし、「フッテージを置き換え」→「ファイル…」を選んで、正しいファイルを選び直すことです。

  • メニューの「ファイル」→「依存関係」→「不明なフッテージを検索」を選び、見つからない素材を確認する
  • 不明なフッテージを右クリックして「フッテージを置き換え」→「ファイル…」を選ぶ
  • 正しいファイルを選んで「開く」を押す
  • すべて直ったら、プロジェクトを保存する

💡 次回から同じ問題を起こさないために、別のPCや外注先にプロジェクトを渡す時は、メニューの「ファイル」→「依存関係」→「ファイルを収集…」で、使っている素材を1つのフォルダにまとめてから渡すのが安全です。

こっこちゃん「でも、素材が50個も60個もあると、1個ずつ選び直すのは気が遠くなります……」

白い鴉「そういう時のために、同じ名前のファイルを自動で探して直すスクリプトを作ったんだ。次の章で紹介するね」

🔗 スクリプト「リンクオート」で一括再リンク

「リンクオート」は、指定したフォルダの中を調べて、不明なフッテージと同じファイル名のファイルを探し、自動で再リンクするスクリプトです。照合のルールは次の通りです。

同名ファイルが1件ならそのまま接続し、複数なら親フォルダ名が最も一致するものを選び、判別できなければ未解決としてレポートに残す照合ルールのインフォグラフィック
  • 1同じ名前のファイルが1つだけ見つかった:そのファイルに再リンクする
  • 2同じ名前のファイルが複数見つかった:元の保存場所と新しい場所で、親フォルダの名前が近い階層から順に何階層分一致するかを比べ、最も多く一致するものを選ぶ(すぐ上のフォルダ名が一致しない場合や、一致数が同じで決められない場合は選ばない)
  • 3見つからない、または決められない:何もせず、「未解決」としてレポートに残す

検索のとき、ゴミ箱やシステム用のフォルダ、After Effectsの自動保存フォルダ(「Adobe After Effects 自動保存」)は対象から外します。名前が「._」で始まるMac由来の隠しファイルや、中身が空のファイルも除外します。

⬇️ ダウンロードと注意事項

コードをコピーして保存するのが面倒な方向けに、zipでも配布しています。

⬇️ ツールのダウンロード

AE_リンクオート v1.0(zip・約5KB)
中身:AE_リンクオート.jsx/説明書.txt

⚠️ ご利用前に必ずお読みください(自己責任・バージョンについて)

  • 自作のツールです。無保証で、ご利用は自己責任でお願いします。利用によって生じたデータの損失・不具合などについて、作者は責任を負いません。
  • 実行する前に、必ずプロジェクトを保存し、できればコピーを取ってください。
  • 動作確認環境は、Windows 11(25H2)とAfter Effects 2026(26.5)です。他のバージョン(古いAfter Effects、Macなど)では、動かない・動作が変わることがあります。After Effectsのバージョンアップで動かなくなる可能性もあります。

📥 導入手順

スクリプトは「ScriptUI Panels」フォルダに入れておくと、After Effectsの「ウィンドウ」メニューの一番下から、いつでもパネルとして開けるようになります。

スクリプトをScriptUI Panelsフォルダに入れ、環境設定でファイル書き込みを許可し、ウィンドウメニューから開く導入手順のインフォグラフィック
  • ダウンロードしたzipを展開して、「AE_リンクオート.jsx」を取り出す(zipを使わない場合は、この記事のコード全文をコピーしてメモ帳などに貼り付け、「AE_リンクオート.jsx」という名前で、文字コードを「UTF-8(BOM付き)」にして保存する。日本語の文字化けを防ぐため)
  • 保存したファイルを、After Effectsがインストールされているフォルダの「Support Files」→「Scripts」→「ScriptUI Panels」に入れる(Windowsの例:C:\Program Files\Adobe\Adobe After Effects 2026\Support Files\Scripts\ScriptUI Panels)
  • After Effectsを起動する(起動中だった場合は再起動する)
  • メニューの「ウィンドウ」の一番下にある「AE_リンクオート.jsx」を選ぶ
  • メニューの「編集」→「環境設定」→「スクリプトとエクスプレッション」で、「スクリプトによるファイルへの書き込みとネットワークへのアクセスを許可」にチェックを入れる(レポートのテキストファイルを保存するために必要)

💡 ScriptUI Panelsフォルダに入れず、「ファイル」→「スクリプト」→「スクリプトファイルを実行…」から、保存した.jsxファイルを選んで一時的に使うこともできます。Program Files内のフォルダへの保存は、管理者権限の確認が出る場合があります。

▶️ 使い方

対象のプロジェクトを開いた状態で、リンクオートのパネルを開きます。「検索フォルダ」に素材が入っているフォルダを指定します(複数のフォルダを探したい時は、「複数フォルダモード」にチェックを入れて、フォルダを追加します)。

変更せずに確認する安全チェックと、実際に再リンクする自動リンクの2つのボタンの違いを示すインフォグラフィック
  • ✅安全チェック:プロジェクトを変更せず、「何件が再リンクできそうか」だけを調べてレポートに出力する。最初に必ずこちらで確認する
  • 🔗自動リンク:実際に再リンクを実行する。実行後に内容を確認して、プロジェクトを保存する

実行すると、「接続○件/未解決○件」と表示され、結果をまとめたテキストファイル「AE_リンクオート_日付_時刻.txt」が作られます。プロジェクトを保存済みの場合はプロジェクトと同じフォルダに、未保存の場合は検索フォルダの先頭に保存されます。レポートには、どの素材をどのファイルにつないだか、つなげなかった素材とその元の場所が一覧で残ります。

💡 自動リンクを実行したあとに間違いに気づいた場合は、Ctrl+Z(MacはCmd+Z)で、再リンクした分を一括で取り消せます。

📋 スクリプトのコード全文

下のコードをそのままコピーして使えます。ExtendScript(After Effects用のJavaScript)で書かれています。

📋 AE_リンクオート.jsx のコード全文(クリックで開く)
/* AE_リンクオート.jsx - safe missing-footage relinker, single or multiple roots. */
(function AE_LinkAuto(thisObj) {
    var SCRIPT_NAME = "リンクオート";
    function isMissing(item) {
        if (!(item instanceof FootageItem) || !item.mainSource) return false;
        try {
            return item.file && !item.file.exists;
        } catch (e) {
            return true;
        }
    }
    function key(s) {
        return String(s).toLowerCase();
    }
    function slash(s) {
        return String(s).replace(/\\/g, "/").toLowerCase();
    }
    function scorePath(oldPath, newPath) {
        var a = slash(oldPath).split("/"),
            b = slash(newPath).split("/"),
            score = 0,
            i,
            max = Math.min(a.length, b.length);
        for (i = 2; i <= max; i++) {
            if (a[a.length - i] === b[b.length - i]) score += 10;
            else break;
        }
        return score;
    }
    function addFile(file, index, seen, state) {
        var path = slash(file.fsName),
            k;
        if (seen[path]) return;
        seen[path] = true;
        k = key(file.name);
        if (!index[k]) index[k] = [];
        index[k].push(file);
        state.count++;
    }
    function scan(folder, index, seen, state) {
        var list, i, entry;
        try {
            list = folder.getFiles();
        } catch (e) {
            return;
        }
        for (i = 0; i < list.length; i++) {
            entry = list[i];
            if (entry instanceof Folder) {
                if (
                    entry.name !== "$RECYCLE.BIN" &&
                    entry.name !== "System Volume Information" &&
                    entry.name !== "__MACOSX" &&
                    entry.name !== "Adobe After Effects 自動保存"
                )
                    scan(entry, index, seen, state);
            } else if (entry.name.indexOf("._") !== 0 && entry.length > 0) addFile(entry, index, seen, state);
        }
    }
    function pick(candidates, oldPath) {
        var i,
            score,
            best = -1,
            second = -1,
            chosen = null;
        if (!candidates || candidates.length === 0) return null;
        if (candidates.length === 1) return { file: candidates[0], why: "同名候補が1件" };
        for (i = 0; i < candidates.length; i++) {
            score = scorePath(oldPath, candidates[i].fsName);
            if (score > best) {
                second = best;
                best = score;
                chosen = candidates[i];
            } else if (score > second) second = score;
        }
        if (best >= 10 && best > second) return { file: chosen, why: "フォルダ構成が最も一致" };
        return null;
    }
    function stamp() {
        var d = new Date();
        function p(n) {
            return n < 10 ? "0" + n : String(n);
        }
        return (
            d.getFullYear() +
            p(d.getMonth() + 1) +
            p(d.getDate()) +
            "_" +
            p(d.getHours()) +
            p(d.getMinutes()) +
            p(d.getSeconds())
        );
    }
    function reportFolder(roots) {
        try {
            if (app.project.file) return app.project.file.parent;
        } catch (e) {}
        return roots[0];
    }
    function run(roots, replace, output) {
        var index = {},
            seen = {},
            state = { count: 0 },
            missing = [],
            repaired = [],
            unresolved = [],
            i,
            j,
            item,
            oldPath,
            chosen,
            report,
            rootText = "";
        if (!app.project || app.project.numItems === 0) {
            alert("対象のAEプロジェクトを開いてから実行してください。");
            return;
        }
        output.text = "🔍 素材を検索中…";
        for (i = 0; i < roots.length; i++) {
            scan(roots[i], index, seen, state);
            rootText += roots[i].fsName + "\n";
        }
        for (i = 1; i <= app.project.numItems; i++)
            if (isMissing(app.project.item(i))) missing.push(app.project.item(i));
        if (missing.length === 0) {
            output.text = "✅ 不明なフッテージはありません。";
            alert(output.text);
            return;
        }
        if (replace) app.beginUndoGroup("リンクオート");
        for (i = 0; i < missing.length; i++) {
            item = missing[i];
            try {
                oldPath = item.file ? item.file.fsName : item.name;
            } catch (e1) {
                oldPath = item.name;
            }
            chosen = pick(index[key(item.name)], oldPath);
            if (chosen && replace) {
                try {
                    item.replace(chosen.file);
                    repaired.push(item.name + "\t" + chosen.why + "\t" + chosen.file.fsName);
                } catch (e2) {
                    unresolved.push(item.name + "\t置換エラー\t" + e2.toString() + "\t" + oldPath);
                }
            } else if (chosen)
                repaired.push(item.name + "\t接続可能: " + chosen.why + "\t" + chosen.file.fsName);
            else unresolved.push(item.name + "\t候補なし/候補が曖昧\t" + oldPath);
        }
        if (replace) app.endUndoGroup();
        report = new File(reportFolder(roots).fsName + "/AE_リンクオート_" + stamp() + ".txt");
        report.encoding = "UTF-8";
        if (report.open("w")) {
            report.writeln("検索フォルダ:");
            report.writeln(rootText);
            report.writeln("検索ファイル数\t" + state.count);
            report.writeln("不明フッテージ\t" + missing.length);
            report.writeln((replace ? "接続済み" : "接続可能") + "\t" + repaired.length);
            report.writeln("未解決\t" + unresolved.length);
            report.writeln("--- " + (replace ? "接続済み" : "接続可能") + " ---");
            for (j = 0; j < repaired.length; j++) report.writeln(repaired[j]);
            report.writeln("--- 未解決 ---");
            for (j = 0; j < unresolved.length; j++) report.writeln(unresolved[j]);
            report.close();
        }
        output.text =
            (replace ? "🔗 接続" : "✅ 接続可能") +
            " " +
            repaired.length +
            "件 / 未解決 " +
            unresolved.length +
            "件\nレポート: " +
            report.fsName;
        alert(
            output.text +
                "\n\n" +
                (replace
                    ? "内容を確認してCtrl+Sで保存してください。"
                    : "[安全チェック]はプロジェクトを変更しません。")
        );
    }
    function buildUI(thisObj) {
        var pal =
            thisObj instanceof Panel
                ? thisObj
                : new Window("palette", SCRIPT_NAME, undefined, { resizeable: true });
        pal.orientation = "column";
        pal.alignChildren = ["fill", "top"];
        pal.add("statictext", undefined, "🔍 リンクオート  ―  不明フッテージを安全に再接続");
        var mode = pal.add("checkbox", undefined, "🗂 複数フォルダモード(登録フォルダを一括検索)");
        var single = pal.add("group");
        single.add("statictext", undefined, "検索フォルダ:");
        var path = single.add("edittext", undefined, "");
        path.characters = 37;
        var choose = single.add("button", undefined, "📁 選択…");
        var multi = pal.add("panel", undefined, "候補の親フォルダ");
        multi.orientation = "column";
        multi.alignChildren = ["fill", "top"];
        var roots = multi.add("listbox", undefined, [], { multiselect: false });
        roots.preferredSize.height = 88;
        var rootButtons = multi.add("group");
        var add = rootButtons.add("button", undefined, "➕ 追加…");
        var remove = rootButtons.add("button", undefined, "➖ 選択を削除");
        var buttons = pal.add("group");
        var check = buttons.add("button", undefined, "✅ 安全チェック");
        var relink = buttons.add("button", undefined, "🔗 自動リンク");
        var out = pal.add("edittext", undefined, "検索フォルダを選択してください。", {
            multiline: true,
            readonly: true
        });
        out.preferredSize.height = 58;
        multi.visible = false;
        function addRoot(folder) {
            var i;
            if (!folder || !folder.exists) return;
            for (i = 0; i < roots.items.length; i++)
                if (slash(roots.items[i].text) === slash(folder.fsName)) return;
            roots.add("item", folder.fsName);
        }
        function chooseFolder() {
            return Folder.selectDialog("素材を探す親フォルダを選択");
        }
        function setMode() {
            single.visible = !mode.value;
            multi.visible = mode.value;
            pal.layout.layout(true);
        }
        mode.onClick = setMode;
        choose.onClick = function () {
            var f = chooseFolder();
            if (f) path.text = f.fsName;
        };
        add.onClick = function () {
            addRoot(chooseFolder());
        };
        remove.onClick = function () {
            if (roots.selection) roots.remove(roots.selection);
        };
        function selectedRoots() {
            var result = [],
                i,
                f;
            if (!mode.value) {
                f = new Folder(path.text);
                if (!path.text || !f.exists) {
                    alert("存在する検索フォルダを選択してください。");
                    return null;
                }
                result.push(f);
                return result;
            }
            for (i = 0; i < roots.items.length; i++) {
                f = new Folder(roots.items[i].text);
                if (f.exists) result.push(f);
            }
            if (result.length === 0) {
                alert("候補の親フォルダを1件以上追加してください。");
                return null;
            }
            return result;
        }
        check.onClick = function () {
            var r = selectedRoots();
            if (r) run(r, false, out);
        };
        relink.onClick = function () {
            var r = selectedRoots();
            if (r) run(r, true, out);
        };
        pal.onResizing = pal.onResize = function () {
            this.layout.resize();
        };
        return pal;
    }
    var panel = buildUI(thisObj);
    if (panel instanceof Window) {
        panel.center();
        panel.show();
    }
})(this);

⚠️ 注意点とできないこと

  • ファイル名が変わった素材は見つけられない:照合は「ファイル名が同じかどうか」だけなので、名前を変えたファイルは未解決になる
  • 同名ファイルが複数あって決められない場合は、つながない:間違った素材につなぐよりも安全なため。レポートの「未解決」を見て、手動で直す
  • 連番素材は未解決になる場合がある:連番画像は項目名が「ファイル名[0001-0100]」のような形になるため、同名ファイルが見つからないことがある
  • 広い範囲を指定すると時間がかかる:ドライブ全体ではなく、その案件の素材フォルダを指定する
  • 実行前にプロジェクトを保存し、実行後に確認してから保存し直す:必ず先に「安全チェック」で結果を確認する

❓ よくある質問

Q. スクリプトを実行しても何も起きません。

A. プロジェクトに不明なフッテージがない場合は、「不明なフッテージはありません」と表示されて終わります。また、プロジェクトが開かれていない場合や、検索フォルダが存在しない場合は、確認のメッセージが出ます。

Q. 日本語の部分が文字化けしてしまいます。

A. .jsxファイルの文字コードが原因の場合があります。メモ帳で保存し直す時に、文字コードを「UTF-8(BOM付き)」にして保存してみてください。

Q. レポートのテキストファイルが作られません。

A. 環境設定の「スクリプトとエクスプレッション」で、「スクリプトによるファイルへの書き込みとネットワークへのアクセスを許可」にチェックが入っているか確認してください。オフのままだと、レポートは保存されません。

Q. Macでも使えますか?

A. Windowsで作って確認したスクリプトです。Macでも同じ手順で導入できます。ScriptUI Panelsフォルダは「アプリケーション」→「Adobe After Effects 2026」→「Scripts」→「ScriptUI Panels」にあり、環境設定は「After Effects」メニュー→「設定」→「スクリプトとエクスプレッション」から開きます。ただし、動作の確認はWindowsで行っています。

📋 まとめ

  • 不明なフッテージは、素材の場所や名前が変わって、プロジェクトが素材を見つけられない状態
  • 基本の直し方は「フッテージを置き換え」→「ファイル…」で、1つずつ選び直すこと
  • 数が多い時は、同名ファイルを自動で探して再リンクするスクリプト「リンクオート」が便利
  • 最初に「安全チェック」で確認し、自動リンク後は内容を確認してから保存する
  • 名前が変わった素材や、同名で決められない素材は、手動で直す

スクリプトの詳しい扱い方は、Adobe公式の「After Effects のスクリプト」にもまとまっています。

次に読む記事

プロジェクトパネルの素材を種類別に自動で整理する方法はAfter Effectsのプロジェクトパネルの整理を自動化する方法、動作が重い時の対処はAfter Effectsが重い・プレビューがカクつく時の対処法もあわせてご覧ください。

ABOUT ME
記事URLをコピーしました