過去のFlashコンテンツをどのように再利用するか

Adobeが2020年にFlashのサポートを終了することを発表しました。
http://jp.techcrunch.com/2017/07/26/20170725get-ready-to-say-goodbye-to-flash-in-2020/

Webコンテンツ製作者の中には、過去の資産をどう活かしたら良いか気になってる人も多いと思うので、再利用方法を書いてみます。お仕事で10年ほど前から5年前くらいにかけてFlash製作に関わっていたこともあるので、その経験から考えられることを書きます。なお、5年前からFlashコンテンツを作っていないため、新しい動向には詳しくありません。具体的な方法について気になる方は、より詳しい記事を探してみてください。

この記事では、Flash Pro CS6以前に作られた、ActionScriptのFlashコンテンツの再利用方法について書いていきます。

# SWFファイルをJavaScriptのライブラリ内で実行する

まだ個人的に詳しく調べられていませんが、Mozilla (ブラウザのFirefoxを作っている会社) が、ShumwayというJavaScript製のFlashプレーヤーを作っています。
https://github.com/mozilla/shumway

このプレイヤー上でSWFを再生することができれば、SWFファイルをHTML + JavaScriptに変換する手間をかける必要がなくなりそうです。実際にこのプレイヤーを使用したことはないので、気になるかたは実行して試してみるか、他の記事を検索してみてください。

### 追記

Shumwayは開発停止されているようです。今現在のバージョンから、おそらく更新されることはないでしょう。

- Components for Firefox Graveyard  
  - https://bugzilla.mozilla.org/describecomponents.cgi?product=Firefox%20Graveyard

### 2020/11/21 追記

Ruffle という JavaScript のライブラリを使うと、 Flash プレイヤーの代わりになるかもしれません。

- Ruffle | Flash Player emulator written in the Rust programming language
  - https://ruffle.rs/
  - https://github.com/ruffle-rs/ruffle

ライセンス

- Apache License, Version 2.0
- MIT license

注意点

- Ruffle は内部で WebAssembly を使っているようなので、比較的新しいブラウザでしか動作しないかもしれません。
- SWF ファイルの構造によっては、再生できないものもあるようです。

関連記事

- Ruffle - Rust製のFlashプレイヤー MOONGIFT
  - https://www.moongift.jp/2019/09/ruffle-rust%E8%A3%BD%E3%81%AEflash%E3%83%97%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC/
- 2020年で終了の「Adobe Flash Player」向けゲームに救世主？ フラッシュゲームをエミュレートするプログラム「Ruffle」が開発中
  - https://news.denfaminicogamer.jp/news/190826a


Ruffle は現在も開発が続けられているので、今のところ再生できない SWF ファイルでも、待っていれば動かせるようになるかもしれません。

# FlashコンテンツをHTML5に変換する

上で紹介したShumwayで再生できない場合や、大きなライブラリをHTML読み込み時にロードしたくない場合は、何らかの方法で変換する必要が出てきます。FlashコンテンツをHTMLに変換する場合は、次の２つのうち、ケースに応じて方法を考える必要があります。

- 手元にSWFファイルのみ残っている場合
- 手元にソースコードが全て残っている場合

## 手元にSWFファイルのみ残っている場合

flaファイル、画像・音声ファイル、ActionScriptのソースコード等が残っていないケースが多々あると思います。Flash製作を外注していた場合はこのケースが当てはまることがあるでしょう。

### SWF変換ツールを利用する

JavaScriptのライブラリ、CreateJSの形式に変換できるツールがあるようです。

- Zoë | A tool for exporting SWF animations as EaselJS sprite sheets.  
http://www.createjs.com/zoe

Googleが作っていたSWF変換ツールSwiffy (現在は開発停止) からフォークしたツールがGithubに残っているっぽいです。

- Search · swiffy  
https://github.com/search?utf8=%E2%9C%93&q=swiffy&type=

### SWFをデコンパイルしてソースコードに戻す

難読化の処理が入っていなければ、書き直せる程度のソースコードに復元できるかもしれません。

- JPEXS Free Flash Decompiler - Opensource SWF decompiler and editor  
https://www.free-decompiler.com/flash/
- SWF Decompiler: フラッシュデコンパイラトリーリックス - SWFデコンパイラ - フラッシュエディター - SWFからFLAへのコンバーター  
http://www.flash-decompiler.com/jp/
- フリーで使えるFlash(SWF)のコンパイラ・逆コンパイルツール|てくめも@ecoop.net  
https://www.ecoop.net/memo/archives/flash_swf_decompilers.html

### SWF変換サービスを利用する
SWFの変換サービスを提供している会社も何社かありそうです。日本語で問い合わせが可能な会社もあるので、自力でどうにもならなさそうな場合は相談してみてください。
http://wordpress.ideacompo.com/?p=6403

### SWFをHTML5に変換する時の注意点
どんなコンテンツでも完全に変換できるかというと、そうでもないようです。というのは、そもそもAdobeがSWFフォーマットの完全なドキュメントを公開していないこともあり、ドキュメントに書かれていない機能は、変換サービスの提供者が手探りで変換する必要があるからです。SWFフォーマットの資料は次のURLにあります。

* 仕様書への直リンク
 * https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf
* リンク切れ
 * http://www.adobe.com/jp/devnet/swf.html

ほとんど労力をかけず、正常に変換できるのは、次の全てに当てはまる場合だけだと思います。

- ActionScriptを使用していない
- FlashVideo (flv) を使用していない
- ベクタ画像のアニメーションを使用していない
- SWF内に他のSWFを埋め込んでいない

このリストのいずれかに反するケースでは、変換が困難になるか、かなりのコスト増になると思います。Webのエンジニアでも、Flashのファイルフォーマットに深く精通している人以外は、簡単には解決策が見つからないと思います。

- まずはSWFからHTMLに変換するツールを試してみる
- お金をかけて短期間で解決したい場合は、変換サービスの提供会社に見積もりをお願いする
- ノウハウを溜める必要がある場合、もしくはお金がかけられない場合は、さらに詳しい記事を検索する

## 手元にソースコードが全て残っている場合

部分的にではなく、完全なSWFが出力できるソースコードが残っている場合について書きます。部分的にしか残っていない場合は、上の、"手元にSWFファイルのみ残っている場合" と同じ状況になると思います。ここでは、こういう方法が考えられるのでは？という、エンジニア向けの方法論についてだけ書いてみます。

### Animate CCで変換する
AdobeのAnimate CCを使うことで、簡単なFlashコンテンツであれば変換できるようです。サポートしている機能については、Adobeのサイト等で調べてみてください。数年前の段階では、ActionScriptを使用したFlashコンテンツの変換はサポートされていませんでした。
https://helpx.adobe.com/jp/animate/how-to/convert-flash-ads-to-html5.html

### 手作業で変換 - flaファイルの変換

flaファイル無しで、FlashDevelop等のエンジニア向け開発ツールのみを使って作られたFlashコンテンツを変換する場合に比べると、flaファイルを使っている状況では、変換する作業が1段階難しくなりそうです。flaファイル内には、さまざまなアセット (画像、音声、アニメーション等) を含めることができるのですが、その1つ1つについて、外部に出力する等の前処理をしておく必要があるからです。また、Flashのアニメーションにはベクタ画像を含むことができるので、いまだにHTML5の機能を使っても移植が容易ではない印象があります。

画像ファイルの処理

通常Webで使われるラスタ画像については、パーツごとに、flaファイル内からJPGやPNGファイルを抜き出すことで、JavaScriptから扱いやすくできると思います。ベクタ画像については、個人的にはSVGではなく、PNGで出力しておいた方が良いと思います。SVGをブラウザ内で扱う場合は、実装方法によっては対応デバイスの範囲を狭めることになるかもしれません (数年前のブラウザや、スマホ、ゲーム機上のブラウザをサポート範囲に含めるのは難しいかもしれません)。

flaファイル内にベクタ画像のアニメーションが作られている場合は、さらにHTMLへの変換が難しくなると思います。簡単な拡大縮小と回転、それらのTweenアニメーションの組み合わせであれば移植も難なくできそうですが、モーフィングアニメーションが含まれる場合は、小さな単位でGIFアニメーションを出力するか、フレームごとに連番PNGファイルを出力しておく必要がありそうです。SVGアニメーションで実装する方法は、ブラウザのサポート範囲が狭まると思いますので、個人的には避けた方が良いと思います。モーフィングアニメーションが少ない場合は、Paper.js等のライブラリを使うことで、ベクタ形式のまま、ブラウザのサポート範囲を確保した上で、地道に1つずつ移植することもできるかもしれません。

音声ファイルの処理

音声については、1つずつmp3やogg等の形式に変換すると、JavaScriptで扱いやすくなると思います。

動画ファイルの処理

FlashVideo (flv) は、videoタグではライブラリ無しで再生することが難しいため、mp4へ変換しておくのが良いと思います。

### 手作業で変換 - ソースコードの変換

ActionScriptのソースコードを、JavaScriptに変換する場合について書きます。ActionScriptのコードは、JavaScriptに似ています。また、TypeScriptにより良く似ています。簡単なトランスレータを作ることで、TypeScriptに変換する処理は難なくこなせる気がします。トランスレータは自分で書かなくても、検索すればすでにライブラリがあるかもしれません。自力で書く場合でも、既存のプリプロセッサ (m4とか) が使えるかもしれません。PerlやRubyでソースコードの変換処理を書いても良いかもしれません。

いったんTypeScriptに変換しておくことで、TypeScriptからJavaScriptへの変換時にES5やES6等、対応ブラウザに合わせてJavaScriptの出力形式を選ぶことができます。

ActionScriptのコードが変換できたとしても、Flashの組み込みクラスの移植はどうするのか？という問題が残ります。変換対象となるActionScriptのコードの複雑さによって移植の方針を変えた方が良いかもしれません。

処理内容ごとに、考えておいた方が良さそうなことを箇条書きで挙げてみます。

画像の処理

- CreateJSの機能の呼び出しに変換することができないか調べてみる (CreateJSはAdobeの人が作っていた気がします。ActionScriptのAPIに似せてあります。)
- ラスタ画像のみを使用している場合は、HTML5のCanvasへの描画クラスを新たに追加する (個人的にはCanvasを直接操作するのではなく、PixiJS経由でCanvas操作をするのがおすすめです。Flashには表示リストという木構造の概念があります。表示リストがサポートされているライブラリを使用した方が負担が少ないです。)
- ベクタ画像を使用している場合は、ベクタ画像を扱うことができるJavaScriptのライブラリを試してみる (Paper.jsとか)
- Canvas内に全て描画するか、上にdivタグを載せて描画した方が良いか切り分ける
- Canvasを何層にも上に積み重ねて、レイヤー構造にした方が描画が簡単になる場合もありそう (PCだけでしか使えないテクニックかも。。)

音声の処理

- CreateJSの機能の呼び出しに変換することができないか調べてみる
- Web Audio APIの機能を呼び出すクラスを新たに追加する (Web Audio APIでは、波形の生成が必要な場合でもActionScriptのSoundクラスと似たAPIで呼び出すことができます。)
- Web Audio APIを使用することができないデバイスをサポート範囲に含める場合、映像と音声の同期、音声ファイルのプリロード、動的な波形の生成等の処理ができない、もしくは実装が難しい可能性があります。

動画の処理

- FlashVideoを動画エンコードソフトでmp4形式に変換しておく
- videoタグの機能でやりくりできる範囲を調べる (HTMLのvideoタグはActionScriptの動画の処理に比べて、できることが少ない印象があります。)
https://developer.mozilla.org/ja/docs/Web/API/HTMLMediaElement
- RTMP形式のストリーミングビデオを扱う必要がある場合は、video.jsが代わりに使えそう
https://github.com/videojs/video.js


その他の処理

- 入力可能なテキストエリアがFlash内に作られている場合は、Canvas上にinputタグを載せる等の対応が必要になりそうです。入力欄が多い場合は、簡単には移植できない可能性があります。
- JavaScriptではEmbedメタデータタグが使用できないため、すべてのアセットを動的に読み込むコードに変換する必要があります (TypeScriptでは、ts-embedというライブラリを組み込むことでEmbedと同じことができそうです)。
- Flashのアニメーションでは、X軸、Y軸を中心とした回転ができるので、使用するJavaScriptライブラリによっては、奥行方向の表示が崩れる場合がありそうです。
- 3D画像を扱う必要がある場合は、Three.js等、代替となるライブラリを探す必要があります。自力でWebGLを扱うのは労力的におすすめできません。
- Flexを使ったFlashコンテンツは、場合によってはFlash組み込みクラスの移植量が数倍に膨れ上がることが予想できるため、JavaScriptで1から実装しなおした方が良いかもしれません。
- Flashライブラリ (SWC) を使ったコードが含まれる場合は、同等の機能を実現するJavaScriptライブラリを組み込み、ActionScriptで書いていたライブラリ依存のインターフェイスを全て書き換える必要がありそうです。
- FlasCC (Adobe Alchemy) を使ってCのコードをActionScriptに変換していた場合は、Emscriptenが代わりに使えるかもしれません。

# デスクトップ上でスタンドアロンプレイヤーを使用する

Webではなく、デスクトップ上でのみ実行できれば良い場合は、Adobeのスタンドアロンプレーヤーを使用するのが良いと思います。

- Adobe Flash Player - Debug Downloads  
http://www.adobe.com/support/flashplayer/debug_downloads.html

### 2020/11/30 追記

「ふらっしゅえぁえぐぜ」というフリーソフトを使うと、 swf を exe 形式に変換できるようです。
Adobe AIR 形式に変換しているらしいです (Adobe AIR は 2020 年末にサポート終了しません)。

- Flash終了間近！ 「ふらっしゅえぁえぐぜ」でEXEに変換してずっと遊べるようにしよう【レビュー】 - 窓の杜
  - https://forest.watch.impress.co.jp/docs/review/1291844.html

# まとめ

- Shumwayで再生できなかったら、変換処理はコストがかかる (労力的にも金銭的にも)
- 簡単に使える変換ツールで変換できない場合は、変換コストが大幅に大きくなる
- 変換元のFlashコンテンツの複雑さによっては、完全な移植ができない場合がある
- 変換すると動作サポート対象が狭まる場合がある
- ソースコードから移植する場合は、エンジニアの負担が大きい

## 参考URL

検索してみると、ActionScriptから直接JavaScriptに変換できるツールがあるようです。

- AS3JS - ActionScript to JavaScript Transpiler  
    https://as3js.org/
- as3-to-typescript  
    https://www.npmjs.com/package/as3-to-typescript

別のFlashプレーヤーを探すスレッド

- Is there any attempt to save all the classic Flash animations and games like the... | Hacker News  
https://news.ycombinator.com/item?id=14849153