LoginSignup
0
0

More than 1 year has passed since last update.

複数ファイルのドラッグでファイルの中身を確認しようとしてハマったこと

Posted at

これは何

Reactのリハビリ+ついでに触ったことのないnext.jsを触ってみようといろいろ遊んでました。D&Dでドロップされてきたファイルの中身を読み取る処理を書いていたのですが、ファイル読み込み部分で若干ハマったので備忘録として残します。

やりたかったこと

  1. Finderから複数のmp3ファイルをブラウザにD&Dでドロップする
  2. mp3ファイルのメタデータを読み込む
  3. 読み取ったメタデータをリストに表示する

だめだったコード

最初は以下のようにドラッグイベントからitemsを引っ張ってきて、そのアイテムを全て回して取得しようとしました。1つ目のファイルは読み取れましたが、それ以降のファイルの type を読んだ時に中身がなくなっていて読み取れない現象が発生してました。

  const handleDrop = async (e: DragEvent) => {
    const items = e.dataTransfer?.items;

    if (items) {
      const newList = [...data];
      for (const el of Array.from(items)) {
        if (el.type === "audio/mpeg") {
          const audioFile = el.getAsFile();

          if (audioFile) {
            // ファイルのメタデータを読み取る処理
            const audioFileBuffer = await audioFile.arrayBuffer();
            const tags = await mm.parseBuffer(Buffer.from(audioFileBuffer));
            newList.push({
              id: newList.length + 1,
              title: tags.common.title ?? audioFile.name,
              artist: tags.common.artist ?? "",
            });
          }
        }
      }

      setData(newList);
    }
  }

読み取りできたコード

以下のようにforを回す前に getAsFile() までやってしまう形で実装したところ、うまく全ファイルの内容を取得することができました。

forループの中でawaitとかしているので、その処理の間にDragEventから情報が取れなくなってしまうんですかね。このへん公式ドキュメントからその辺の情報を拾おうとしたのですが、まだ見つけられてないですね。。。逆に getAsFile() ってなんか名前的に重そうですけど Promise じゃないんですね。

  const handleDrop = async (e: DragEvent) => {
    const items = e.dataTransfer?.items;

    if (items) {
      const newList = [...data];
      const files = Array.from(items)
        .filter((el) => el.type === "audio/mpeg")
        .map((el) => el.getAsFile());

      for (const audioFile of files) {
        if (audioFile) {
          // ファイルのメタデータを読み取る処理
          const audioFileBuffer = await audioFile.arrayBuffer();
          const tags = await mm.parseBuffer(Buffer.from(audioFileBuffer));
          newList.push({
            id: newList.length + 1,
            title: tags.common.title ?? audioFile.name,
            artist: tags.common.artist ?? "",
          });
        }
      }

      setData(newList);
    }
  }
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0