表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
5/5

番外編 MP3の音楽ファイルの曲名、添付画像などのID3v2タグ編集アプリケーション

 曲名、アーティスト名、アルバム名、トラック番号、添付画像以外の情報は削除してしまいます。注意してください。


 アンドロイドのスマホのシステムはID3v2.4への対応が不完全なよう?なので、MP3ファイルを作成する時にID3v2.3のタグを付加しています。



 不具合が有るかもしれないので、利用は自己責任でお願いいたします。


 不具合でMP3の音楽ファイルを破壊してしまうかもしれないので、元のMP3のファイルをコピーしてバックアップしておいてください。



 コピペする場合は、2文字の全角空白を4文字の半角空白に、全角縦線を|に、置換してください。


 Java11のJDKのjavaコマンドで動作を確認できました。


 例えばMain.javaという名前の内容がからっぽのファイルを作って、Main.javaの内容にコピペして、Java11以降のJDKをインストールして、「java Main.java」といったコマンドで実行します。

import javax.swing.JFrame;

import java.awt.Container;

import javax.swing.JLabel;

import javax.swing.JButton;

import javax.swing.JFileChooser;

import javax.swing.filechooser.FileNameExtensionFilter;

import javax.swing.JTextField;

import javax.swing.JOptionPane;

import javax.swing.ImageIcon;


import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.Files;

import java.nio.file.StandardOpenOption;


import java.nio.charset.Charset;

import java.nio.charset.StandardCharsets;


import java.util.ArrayList;

import java.util.Arrays;


import java.io.BufferedOutputStream;


public class Main {


  private static String imageMimetype = null;

  private static ArrayList<Byte> imageByteList = new ArrayList<>();

  private static ArrayList<Byte> mpegFrameByteList = new ArrayList<>();


  public static void main(String[] args) throws Exception {

    JFrame frame = new JFrame();

    frame.setTitle("MP3のID3v2タグ編集"); //ウィンドウのタイトルバーのタイトル

    frame.setSize(800, 700); //初期表示のウィンドウの横幅と高さ

    frame.setLocationRelativeTo(null); //モニターの中央に表示

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //ウィンドウ右上のXボタンで終了


    Container container = frame.getContentPane();

    container.setLayout(null); //LayoutManagerを使わず座標を指定して自由に配置


    JLabel mp3Label = new JLabel("");

    mp3Label.setSize(10, 10);

    mp3Label.setLocation(10, 40); //座標を指定

    container.add(mp3Label);


    JButton mp3SelectButton = new JButton("MP3ファイル選択");

    mp3SelectButton.setSize(240, 20);

    mp3SelectButton.setLocation(10, 10); //座標を指定

    container.add(mp3SelectButton);


    JLabel newMP3FileNameLabel = new JLabel("新MP3ファイル名");

    newMP3FileNameLabel.setSize(100, 10);

    newMP3FileNameLabel.setLocation(10, 60); //座標を指定

    container.add(newMP3FileNameLabel);


    JTextField newMP3FileNameTextField = new JTextField(80);

    newMP3FileNameTextField.setSize(640, 20);

    newMP3FileNameTextField.setLocation(110, 60); //座標を指定

    container.add(newMP3FileNameTextField);


    JLabel titleLabel = new JLabel("曲名");

    titleLabel.setSize(100, 10);

    titleLabel.setLocation(10, 90); //座標を指定

    container.add(titleLabel);


    JTextField titleTextField = new JTextField(80);

    titleTextField.setSize(640, 20);

    titleTextField.setLocation(110, 90); //座標を指定

    container.add(titleTextField);


    JLabel artistLabel = new JLabel("アーティスト名");

    artistLabel.setSize(100, 10);

    artistLabel.setLocation(10, 120); //座標を指定

    container.add(artistLabel);


    JTextField artistTextField = new JTextField(80);

    artistTextField.setSize(640, 20);

    artistTextField.setLocation(110, 120); //座標を指定

    container.add(artistTextField);


    JLabel albumLabel = new JLabel("アルバム名");

    albumLabel.setSize(100, 10);

    albumLabel.setLocation(10, 150); //座標を指定

    container.add(albumLabel);


    JTextField albumTextField = new JTextField(80);

    albumTextField.setSize(640, 20);

    albumTextField.setLocation(110, 150); //座標を指定

    container.add(albumTextField);


    JLabel trackLabel = new JLabel("トラック番号");

    trackLabel.setSize(100, 10);

    trackLabel.setLocation(10, 180); //座標を指定

    container.add(trackLabel);


    JTextField trackTextField = new JTextField(80);

    trackTextField.setSize(640, 20);

    trackTextField.setLocation(110, 180); //座標を指定

    container.add(trackTextField);


    JButton makeMp3Button = new JButton("新MP3ファイル作成");

    makeMp3Button.setSize(240, 20);

    makeMp3Button.setLocation(10, 210); //座標を指定

    container.add(makeMp3Button);


    JLabel imageLabel = new JLabel("画像 無し");

    imageLabel.setSize(800, 300);

    imageLabel.setLocation(10, 240); //座標を指定

    container.add(imageLabel);


    JButton imageSelectButton = new JButton("画像ファイル選択");

    imageSelectButton.setSize(240, 20);

    imageSelectButton.setLocation(10, 560); //座標を指定

    container.add(imageSelectButton);



    //MP3ファイル選択ボタンが押された時の処理

    mp3SelectButton.addActionListener(

      actionEvent -> {

        try {

          JFileChooser fileChooser = new JFileChooser();

          fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

          fileChooser.setFileFilter(new FileNameExtensionFilter("MP3", "mp3"));

          if (fileChooser.showOpenDialog(container) == JFileChooser.APPROVE_OPTION) {


            if (fileChooser.getSelectedFile().getAbsolutePath().matches("^.+\\.[mM][pP]3$") == false) {

              JOptionPane.showMessageDialog(frame, "MP3ファイルを選択してください。");

              return;

            }


            mp3Label.setText(fileChooser.getSelectedFile().getAbsolutePath());

            mp3Label.setSize(mp3Label.getText().length() * 20, 10);


            byte[] byteArray = Files.readAllBytes(fileChooser.getSelectedFile().toPath());


            newMP3FileNameTextField.setText("新" + fileChooser.getSelectedFile().toPath().getFileName());

            titleTextField.setText("");

            artistTextField.setText("");

            albumTextField.setText("");

            trackTextField.setText("");


            imageLabel.setText("画像 無し");

            imageLabel.setIcon(null);


            imageMimetype = null;

            imageByteList.clear();

            mpegFrameByteList.clear();


            String id3 = new String(Arrays.copyOfRange(byteArray, 0, 3), StandardCharsets.UTF_8);

            if (id3.equals("ID3") == false) {

              //ID3v2タグが無い場合

              for (int index = 0; index < byteArray.length; index++) {

                mpegFrameByteList.add(byteArray[index]);

              }

              return;

            }


            int minorVersion = Byte.toUnsignedInt(byteArray[3]);

            if (minorVersion <= 2 || 5 <= minorVersion) {

              JOptionPane.showMessageDialog(frame, "当アプリケーションはID3v2.3とID3v2.4以外には未対応です。\n他のアプリケーションを利用してください。");

              return;

            }


            //int batchVersion = Byte.toUnsignedInt(byteArray[4]);


            byte flag = byteArray[5];

            boolean hasExHeader = ((flag & 0x02) != 0);

            int headerSize = 0;

            headerSize += (Byte.toUnsignedInt(byteArray[6]) << 21);

            headerSize += (Byte.toUnsignedInt(byteArray[7]) << 14);

            headerSize += (Byte.toUnsignedInt(byteArray[8]) << 7);

            headerSize += Byte.toUnsignedInt(byteArray[9]);


            int byteIndex = 10;


            if (hasExHeader) {

              int exHeaderSize = 0;

              if (minorVersion == 3) {

                exHeaderSize += (Byte.toUnsignedInt(byteArray[10]) << 24);

                exHeaderSize += (Byte.toUnsignedInt(byteArray[11]) << 16);

                exHeaderSize += (Byte.toUnsignedInt(byteArray[12]) << 8);

                exHeaderSize += Byte.toUnsignedInt(byteArray[13]);

              } else {

                exHeaderSize += (Byte.toUnsignedInt(byteArray[10]) << 21);

                exHeaderSize += (Byte.toUnsignedInt(byteArray[11]) << 14);

                exHeaderSize += (Byte.toUnsignedInt(byteArray[12]) << 7);

                exHeaderSize += Byte.toUnsignedInt(byteArray[13]);

              }

              byteIndex += exHeaderSize;

            }


            while (byteIndex < headerSize) {


              String frameId = new String(Arrays.copyOfRange(byteArray, byteIndex, byteIndex + 4), StandardCharsets.UTF_8);

              byteIndex += 4;


              if (byteIndex == 14 && frameId.matches("^[A-Z][A-Z][A-Z][A-Z0-9]$") == false) {

                byteIndex -= 4;

                int exHeaderSize = 0;

                if (minorVersion == 3) {

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[10]) << 24);

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[11]) << 16);

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[12]) << 8);

                  exHeaderSize += Byte.toUnsignedInt(byteArray[13]);

                } else {

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[10]) << 21);

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[11]) << 14);

                  exHeaderSize += (Byte.toUnsignedInt(byteArray[12]) << 7);

                  exHeaderSize += Byte.toUnsignedInt(byteArray[13]);

                }

                byteIndex += exHeaderSize;

                continue;

              }



              int frameSize = 0;

              if (minorVersion == 3) {

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex]) << 24);

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex + 1]) << 16);

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex + 2]) << 8);

                frameSize += Byte.toUnsignedInt(byteArray[byteIndex + 3]);

              } else {

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex]) << 21);

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex + 1]) << 14);

                frameSize += (Byte.toUnsignedInt(byteArray[byteIndex + 2]) << 7);

                frameSize += Byte.toUnsignedInt(byteArray[byteIndex + 3]);

              }

              byteIndex += 4;


              byteIndex += 2; //フレームのフラグは無視して飛ばします。


              if (frameId.matches("^TIT2$|^TPE1$|^TALB$|^TRCK$")) {


                byte encodingByte = byteArray[byteIndex];

                Charset charset = null;

                if (encodingByte == 0x00) {

                  //charset = Charset.forName("ISO-8859-1");

                  charset = Charset.forName("Windows-31J"); //過去の日本語のアプリケーションにはISO-8859-1でWindowsの日本語のテキストを書き込んでいた物が有ったそうです。

                } else if (encodingByte == 0x01) {

                  charset = Charset.forName("UTF-16");

                } else if (minorVersion == 4 && encodingByte == 0x02) {

                  charset = Charset.forName("UTF-16BE");

                } else if (minorVersion == 4 && encodingByte == 0x03) {

                  charset = Charset.forName("UTF-8");

                } else {

                  throw new Exception("存在しないID3v2マイナーバージョンとテキスト エンコーディングの16進数表記の組み合わせです。");

                }

                byteIndex += 1;


                String content = "";


                ArrayList<Byte> contentByteList = new ArrayList<>();

                for (int index = 0; index < frameSize - 1; index++) {

                  contentByteList.add(byteArray[byteIndex + index]);

                }

                byteIndex += contentByteList.size();

                byte[] contentByteArray = new byte[contentByteList.size()];

                for (int index = 0; index < contentByteArray.length; index++) {

                  contentByteArray[index] = contentByteList.get(index);

                }

                content = new String(contentByteArray, charset);


                if (frameId.equals("TIT2")) {

                  titleTextField.setText(content);

                } else if (frameId.equals("TPE1")) {

                  artistTextField.setText(content);

                } else if (frameId.equals("TALB")) {

                  albumTextField.setText(content);

                } else if (frameId.equals("TRCK")) {

                  trackTextField.setText(content);

                }


              } else if (frameId.equals("APIC")) {


                byte encodingByte = byteArray[byteIndex];

                Charset charset = null;

                if (encodingByte == 0x00) {

                  //charset = Charset.forName("ISO-8859-1");

                  charset = Charset.forName("Windows-31J"); //過去の日本語のアプリケーションにはISO-8859-1でWindowsの日本語のテキストを書き込んでいた物が有ったそうです。

                } else if (encodingByte == 0x01) {

                  charset = Charset.forName("UTF-16");

                } else if (minorVersion == 4 && encodingByte == 0x02) {

                  charset = Charset.forName("UTF-16BE");

                } else if (minorVersion == 4 && encodingByte == 0x03) {

                  charset = Charset.forName("UTF-8");

                } else {

                  throw new Exception("存在しないID3v2マイナーバージョンとテキスト エンコーディングの16進数表記の組み合わせです。");

                }

                byteIndex += 1;


                ArrayList<Byte> mimetypeByteList = new ArrayList<>();

                for (int index = 0; index < frameSize - 1; index++) {

                  byte currentByte = byteArray[byteIndex + index];

                  if (currentByte == 0x00/* NULL */) {

                    break;

                  }

                  mimetypeByteList.add(currentByte);

                }

                byte[] mimetypeByteArray = new byte[mimetypeByteList.size()];

                for (int index = 0; index < mimetypeByteArray.length; index++) {

                  mimetypeByteArray[index] = mimetypeByteList.get(index);

                }

                imageMimetype = new String(mimetypeByteArray, charset);

                byteIndex += (mimetypeByteList.size() + 1);


                byteIndex += 1; //Picture Type(画像の種類)を無視して飛ばします。


                ArrayList<Byte> descriptionList = new ArrayList<>();

                for (int index = 0; index < (frameSize - 1 - mimetypeByteList.size() - 1 - 1); index++) {

                  byte currentByte = byteArray[byteIndex + index];

                  if (currentByte == 0x00/* NULL */) {

                    break;

                  }

                  descriptionList.add(currentByte);

                }

                byteIndex += (descriptionList.size() + 1);


                for (int index = 0; index < (frameSize - 1 - mimetypeByteList.size() - 1 - 1 - descriptionList.size() - 1); index++) {

                  imageByteList.add(byteArray[byteIndex + index]);

                }

                byte[] imageByteArray = new byte[imageByteList.size()];

                for (int index = 0; index < imageByteArray.length; index++) {

                  imageByteArray[index] = imageByteList.get(index);

                }

                imageLabel.setText("");

                imageLabel.setIcon(new ImageIcon(imageByteArray));


              } else {

                byteIndex += frameSize;

              }

            }


            if (headerSize < byteIndex) {

              byteIndex = headerSize;

            }


            for (; byteIndex < byteArray.length; byteIndex++) {

              mpegFrameByteList.add(byteArray[byteIndex]);

            }

          }

        } catch (Exception exception) {

          JOptionPane.showMessageDialog(frame, "エラー: " + exception);

          throw new RuntimeException(exception);

        }

      }

    );



    //画像ファイル選択ボタンが押された時の処理

    imageSelectButton.addActionListener(

      actionEvent -> {

        try {

          JFileChooser fileChooser = new JFileChooser();

          fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

          fileChooser.setFileFilter(new FileNameExtensionFilter("PNG or JPEG Image", "png", "jpg", "jpeg"));

          if (fileChooser.showOpenDialog(container) == JFileChooser.APPROVE_OPTION) {


            if (fileChooser.getSelectedFile().getAbsolutePath().matches("^.+\\.[pP][nN][gG]$|^.+\\.[jJ][pP][eE]?[gG]$") == false) {

              JOptionPane.showMessageDialog(frame, "PNG形式かJPEG形式の画像ファイルを選択してください。");

              return;

            }


            byte[] byteArray = Files.readAllBytes(fileChooser.getSelectedFile().toPath());


            imageLabel.setText("");


            if (fileChooser.getSelectedFile().getAbsolutePath().matches("^.+\\.[pP][nN][gG]$")) {

              imageMimetype = "image/png";

            } else {

              imageMimetype = "image/jpeg";

            }


            imageByteList.clear();

            for (int index = 0; index < byteArray.length; index++) {

              imageByteList.add(byteArray[index]);

            }

            byte[] imageByteArray = new byte[imageByteList.size()];

            for (int index = 0; index < imageByteArray.length; index++) {

              imageByteArray[index] = imageByteList.get(index);

            }

            imageLabel.setIcon(new ImageIcon(imageByteArray));

          }

        } catch (Exception exception) {

          JOptionPane.showMessageDialog(frame, "エラー: " + exception);

          throw new RuntimeException(exception);

        }

      }

    );



    //新MP3作成ボタンが押された時の処理

    makeMp3Button.addActionListener(actionEvent -> {

      try {


        if (mpegFrameByteList.size() <= 0) {

          JOptionPane.showMessageDialog(frame, "MP3ファイルを選択してください。");

          return;

        }


        String newMP3FileName = newMP3FileNameTextField.getText();

        String title = titleTextField.getText();

        String artist = artistTextField.getText();

        String album = albumTextField.getText();

        String track = trackTextField.getText();


        if (newMP3FileName.isEmpty()) {

          JOptionPane.showMessageDialog(frame, "新MP3ファイル名を記入してください。");

          return;

        }

        if (title.isEmpty()) {

          JOptionPane.showMessageDialog(frame, "曲名を記入してください。");

          return;

        }

        if (artist.isEmpty()) {

          JOptionPane.showMessageDialog(frame, "アーティスト名を記入してください。");

          return;

        }

        if (track.isEmpty()) {

          JOptionPane.showMessageDialog(frame, "トラック番号を記入してください。");

          return;

        }


        String mp3FilePath = mp3Label.getText();


        Path mp3DirPath = Paths.get(mp3FilePath).getParent();


        Path newMp3FilePath = mp3DirPath.resolve(newMP3FileName);


        byte[] titleByteArray = title.getBytes(StandardCharsets.UTF_16);

        byte[] artistByteArray = artist.getBytes(StandardCharsets.UTF_16);

        byte[] albumByteArray = album.getBytes(StandardCharsets.UTF_16);

        byte[] trackByteArray = track.getBytes(StandardCharsets.UTF_16);


        int headerSize = 0;

        headerSize += 10;

        headerSize += (10 + 1 + titleByteArray.length);

        headerSize += (10 + 1 + artistByteArray.length);

        headerSize += (10 + 1 + trackByteArray.length);

        if (album.isEmpty() == false) {

          headerSize += (10 + 1 + albumByteArray.length);

        }

        if (1 <= imageByteList.size()) {

          headerSize += (10 + 1 + imageMimetype.length() + 1 + 1 + 1 + imageByteList.size());

        }


        int fileSize = headerSize + mpegFrameByteList.size();


        try(

          BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(Files.newOutputStream(newMp3FilePath, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING));

        ) {


          //Javaはデフォルトはビッグ エンディアン

          //ID3v2タグはビッグ エンディアン


          bufferedOutputStream.write(0x49/* I */);

          bufferedOutputStream.write(0x44/* D */);

          bufferedOutputStream.write(0x33/* 3 */);

          bufferedOutputStream.write(0x03/* マイナーバージョン3 */);

          bufferedOutputStream.write(0x00/* パッチバージョン0 */);

          bufferedOutputStream.write(0x00/* ヘッダーのフラグ */);

          bufferedOutputStream.write(headerSize << 4 >>> 25);

          bufferedOutputStream.write(headerSize << 11 >>> 25);

          bufferedOutputStream.write(headerSize << 18 >>> 25);

          bufferedOutputStream.write(headerSize << 25 >>> 25);


          bufferedOutputStream.write(0x54/* T */);

          bufferedOutputStream.write(0x49/* I */);

          bufferedOutputStream.write(0x54/* T */);

          bufferedOutputStream.write(0x32/* 2 */);

          bufferedOutputStream.write((1 + titleByteArray.length) >>> 24);

          bufferedOutputStream.write((1 + titleByteArray.length) << 8 >>> 24);

          bufferedOutputStream.write((1 + titleByteArray.length) << 16 >>> 24);

          bufferedOutputStream.write((1 + titleByteArray.length) << 24 >>> 24);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x01/* テキストのフレームの文字コード。BOM付きUTF-16は16進数で01。 */);

          for (int index = 0; index < titleByteArray.length; index++) {

            bufferedOutputStream.write(titleByteArray[index]);

          }


          bufferedOutputStream.write(0x54/* T */);

          bufferedOutputStream.write(0x50/* P */);

          bufferedOutputStream.write(0x45/* E */);

          bufferedOutputStream.write(0x31/* 1 */);

          bufferedOutputStream.write((1 + artistByteArray.length) >> 24);

          bufferedOutputStream.write((1 + artistByteArray.length) << 8 >>> 24);

          bufferedOutputStream.write((1 + artistByteArray.length) << 16 >>> 24);

          bufferedOutputStream.write((1 + artistByteArray.length) << 24 >>> 24);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x01/* テキストのフレームの文字コード。BOM付きUTF-16は16進数で01。 */);

          for (int index = 0; index < artistByteArray.length; index++) {

            bufferedOutputStream.write(artistByteArray[index]);

          }


          bufferedOutputStream.write(0x54/* T */);

          bufferedOutputStream.write(0x52/* R */);

          bufferedOutputStream.write(0x43/* C */);

          bufferedOutputStream.write(0x4B/* K */);

          bufferedOutputStream.write((1 + trackByteArray.length) >>> 24);

          bufferedOutputStream.write((1 + trackByteArray.length) << 8 >>> 24);

          bufferedOutputStream.write((1 + trackByteArray.length) << 16 >>> 24);

          bufferedOutputStream.write((1 + trackByteArray.length) << 24 >>> 24);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x01/* テキストのフレームの文字コード。BOM付きUTF-16は16進数で01。 */);

          for (int index = 0; index < trackByteArray.length; index++) {

            bufferedOutputStream.write(trackByteArray[index]);

          }


          if (album.isEmpty() == false) {

            bufferedOutputStream.write(0x54/* T */);

            bufferedOutputStream.write(0x41/* A */);

            bufferedOutputStream.write(0x4C/* L */);

            bufferedOutputStream.write(0x42/* B */);

            bufferedOutputStream.write((1 + albumByteArray.length) >>> 24);

            bufferedOutputStream.write((1 + albumByteArray.length) << 8 >>> 24);

            bufferedOutputStream.write((1 + albumByteArray.length) << 16 >>> 24);

            bufferedOutputStream.write((1 + albumByteArray.length) << 24 >>> 24);

            bufferedOutputStream.write(0x00/* フレームのフラグ */);

            bufferedOutputStream.write(0x00/* フレームのフラグ */);

          bufferedOutputStream.write(0x01/* テキストのフレームの文字コード。BOM付きUTF-16は16進数で01。 */);

            for (int index = 0; index < albumByteArray.length; index++) {

              bufferedOutputStream.write(albumByteArray[index]);

            }

          }


          if (1 <= imageByteList.size()) {

            bufferedOutputStream.write(0x41/* A */);

            bufferedOutputStream.write(0x50/* P */);

            bufferedOutputStream.write(0x49/* I */);

            bufferedOutputStream.write(0x43/* C */);

            bufferedOutputStream.write((1 + imageMimetype.length() + 1 + 1 + 1 + imageByteList.size()) >>> 24);

            bufferedOutputStream.write((1 + imageMimetype.length() + 1 + 1 + 1 + imageByteList.size()) << 8 >>> 24);

            bufferedOutputStream.write((1 + imageMimetype.length() + 1 + 1 + 1 + imageByteList.size()) << 16 >>> 24);

            bufferedOutputStream.write((1 + imageMimetype.length() + 1 + 1 + 1 + imageByteList.size()) << 24 >>> 24);

            bufferedOutputStream.write(0x00/* フレームのフラグ */);

            bufferedOutputStream.write(0x00/* フレームのフラグ */);

            bufferedOutputStream.write(0x00/* テキストのフレームの文字コード。ISO-8859-1は16進数で00。 */);


            byte[] imageMimetypeByteArray = imageMimetype.getBytes(StandardCharsets.UTF_8); //UTF-8はISO-8859-1を包含


            for (int index = 0; index < imageMimetypeByteArray.length; index++) {

              bufferedOutputStream.write(imageMimetypeByteArray[index]);

            }


            bufferedOutputStream.write(0x00/* NULLの文字コード */);

            bufferedOutputStream.write(0x03/* Picture Type(画像の種類)。Front Cover(表カバー)は16進数で03。 */);

            bufferedOutputStream.write(0x00/* Description(説明)の終了を表すNULLの文字コード。 */);


            byte[] imageByteArray = new byte[imageByteList.size()];

            for (int index = 0; index < imageByteArray.length; index++) {

              imageByteArray[index] = imageByteList.get(index);

            }


            for (int index = 0; index < imageByteArray.length; index++) {

              bufferedOutputStream.write(imageByteArray[index]);

            }

          }


          byte[] mpegFrameByteArray = new byte[mpegFrameByteList.size()];

          for (int index = 0; index < mpegFrameByteArray.length; index++) {

            mpegFrameByteArray[index] = mpegFrameByteList.get(index);

          }


          for (int index = 0; index < mpegFrameByteArray.length; index++) {

            bufferedOutputStream.write(mpegFrameByteArray[index]);

          }

        }


        JOptionPane.showMessageDialog(frame, "新MP3ファイルの作成が完了しました。");


      } catch (Exception exception) {

        JOptionPane.showMessageDialog(frame, "エラー: " + exception);

        throw new RuntimeException(exception);

      }

    });



    frame.setVisible(true); //ウィンドウを表示

  }

}


評価をするにはログインしてください。
この作品をシェア
Twitter LINEで送る
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ