okayurisotto.net

私が好きでやったことが他の人のためにもなったらお得かも!

閲覧中のWebページにある動画のスクリーンショットを撮影するブックマークレットを作った

公開日:

はじめに

閲覧中のWebページにある動画のスクリーンショットを撮影(ダウンロード)するブックマークレットを作りました。

下に示すURIをブックマークして使ってください。

javascript:void((()%3D%3E%7B%22use%20strict%22%3B(()%3D%3E%7B(async()%3D%3E%7Blet%20d%3Dt%3D%3E%7Blet%20e%3Dt.getFullYear().toString().padStart(4%2C%220%22)%2Co%3D(t.getMonth()%2B1).toString().padStart(2%2C%220%22)%2Ca%3Dt.getDate().toString().padStart(2%2C%220%22)%2Cg%3Dt.getHours().toString().padStart(2%2C%220%22)%2Ch%3Dt.getMinutes().toString().padStart(2%2C%220%22)%2Cu%3Dt.getSeconds().toString().padStart(2%2C%220%22)%3Breturn%60%24%7Be%7D-%24%7Bo%7D-%24%7Ba%7D_%24%7Bg%7D-%24%7Bh%7D-%24%7Bu%7D%60%7D%2Cr%3D%5B...document.querySelectorAll(%22video%22)%5D.filter(t%3D%3E%7Blet%20e%3Dt.getBoundingClientRect()%3Breturn!(e.width%3D%3D%3D0%7C%7Ce.height%3D%3D%3D0%7C%7Ce.top%3Ewindow.innerHeight%26%26e.bottom%3Ewindow.innerHeight%7C%7Ce.left%3Ewindow.innerWidth%26%26e.right%3Ewindow.innerWidth)%7D).sort((t%2Ce)%3D%3E%7Blet%20o%3Dt.width*t.height%2Ca%3De.width*e.height%3Breturn%20o%3Ea%3F-1%3Ao%3Ca%3F1%3A0%7D).at(0)%3Bif(!r)return%3Blet%20n%3Ddocument.createElement(%22canvas%22)%3Bn.width%3Dr.videoWidth%2Cn.height%3Dr.videoHeight%3Blet%20s%3Dn.getContext(%222d%22)%3Bif(!s)return%3Bs.drawImage(r%2C0%2C0%2Cn.width%2Cn.height)%3Blet%20i%3Dawait%20new%20Promise(t%3D%3En.toBlob(t))%3Bif(!i)return%3Bnavigator.clipboard%3F.write%26%26navigator.clipboard.write(%5Bnew%20ClipboardItem(%7B%5Bi.type%5D%3Ai%7D)%5D)%3Blet%20l%3DURL.createObjectURL(i)%2Cc%3Ddocument.createElement(%22a%22)%3Bc.download%3Dd(new%20Date)%2B%22_%22%2Blocation.host.replaceAll(%22.%22%2C%22-%22)%2Cc.href%3Dl%2Cc.click()%7D)()%3B%7D)()%3B%0A%7D)())%3B

これだけでは流石に記事として味気ないので、少し技術的な解説をします。

そもそものブックマークレットについて

こちらの記事を参照してください。

このブックマークレットでやっていること

大したことはしていません。

  1. Webページから動画を再生している要素(<video>)を取得
  2. Webページにcanvas要素(<canvas>)を作成
  3. 作成したcanvasに、動画要素を入力値として画像を描く(drawImage()
  4. 描いた画像のデータをObjectURLにする(URL.createObjectURL()
  5. そのURLからダウンロードリンク(<a>)を作成
  6. そのダウンロードリンクを自動クリック

また、対応ブラウザでは画像のクリップボードへのコピーもしています(Clipboard API)。

おわりに

SNSとの連携とかもできたら面白そうだと思いましたが、流石にそこまでやるならブックマークレットではなく拡張機能として実装した方がよさそうな気がしたので、やめておきました。また、このときダウンロードされる画像はPNG形式で、適当にJPEGにするだけで容量が半分になったりします。このあたりの圧縮などもクライアントサイドでやれたらよかったのですが、やはりブックマークレットでやるべきことではないですし、そのあたりの知見も足りていないので今回は見送りました。(Squooshがディスコンしていなければ……。)

このブックマークレットはあくまで技術デモということで、どうかよろしくお願いします。