2014年2月19日 星期三

JavaFX Media (2) Metadata

接著上一篇JavaFX Media (1) Introduction介紹基本的JavaFX Media概念,本篇將說明多媒體的Metadata。

Metadata原意為Data about Data,中文直譯為有關資料的資料或描述資料的資料,國內學者對於Metadata有不同的譯名,常見的有元資料、詮釋資料、超資料等,中央研究院數位典藏與數位學習國家型科技計畫則譯為後設資料,特此說明。請參考以下網址之說明:http://metadata.teldap.tw/share/share-frame.html

在多媒體中,Metadata是指內嵌於音訊與影像檔案中的標籤 (Tag) 資料,常見的標籤與JavaFX所支援的媒體格式如下所示。

音訊類型,適用於MP3媒體格式:
  • album artist:專輯演出者。
  • album:專輯名稱。
  • artist:演出者。
  • composer:作曲者。
  • comment-N:專輯第N首音軌的註解。
  • disc count:專輯光碟數目。
  • disc number:專輯光碟編號。
  • duration:音軌時間長度。
  • genre:音軌類型如流行樂、搖滾樂等。
  • image:專輯封面。
  • title:音軌名稱。
  • track count:音軌總數。
  • track number:音軌編號。
  • year:專輯年份。
影像類型,適用於FLV與FXM媒體格式:
  • audio codec:音訊編碼器。
  • creationdate:媒體建立日期。
  • duration:音訊時間長度。
  • framerate:影像畫格 (Frame) 速率。
  • height:影像高度。
  • width:影像寬度。
  • video codec:影像編碼器。
欲處理Metadata,可使用Media類別的getMetadata()方法取得。由於媒體常會改變,特別是專輯中各音軌的Metadata資料均不同,因此在實作上,會將上述以getMetadata()方法所取得的Metadata資料,再以addListener()方法處理其改變事件,一旦資料改變時,再重新取得相關Metadata資料。

此外,須注意的是JavaFX目前支援取得Metadata資料的媒體格式分別為MP3音訊、FLV影像與FXM影像等,其餘尚未支援。

請參考以下範例,首先以Media類別的getMetadata()方法取得音訊檔案中的Metadata資料,接著以addListener()方法處理其改變事件,在事件中分別判斷各Metadata標籤資料是否改變,藉此更新其內容。須注意的是JavaFX僅支援MP3音訊:


media.getMetadata().addListener(
  new MapChangeListener<String, Object>() {
  @Override public void onChanged(
    MapChangeListener.Change<? extends String, 
    ? extends Object> change) {

    if (change.wasAdded()) {
      String key = change.getKey();
      Object value = change.getValueAdded();

      if (key.equals("album")) {
        lblAlbum.setText("Album: " + value.toString());
      } 
      else if (key.equals("artist")) {
        lblArtist.setText("Artist: " + value.toString());
      } 
      else if (key.equals("composer")) {
        lblComposer.setText("Composer: " + value.toString());
      }
      else if (key.equals("duration")) {
        lblDurations.setText("Duration: " + value.toString());
      } 
      else if (key.equals("genre")) {
        lblGenre.setText("Genre: " + value.toString());
      }
      else if (key.equals("title")) {
        lblTitle.setText("Title: " + value.toString());
      } 
      else if (key.equals("year")) {
        lblYear.setText("Year: " + value.toString());
      } 
      else if (key.equals("image")) {
        imgCover.setImage((Image)value);
      }
    }
  }
});


此外,範例建立一分頁窗格顯示音訊檔案的Metadata資料:


private BorderPane createMetadataPane() {
  lblAlbum = new Label();
  lblAlbum.setText("N/A");
  lblArtist = new Label();
  lblArtist.setText("N/A");
  lblComposer = new Label();
  lblComposer.setText("N/A");
  lblDurations = new Label();
  lblDurations.setText("N/A");
  lblGenre = new Label();
  lblGenre.setText("N/A");
  lblTitle = new Label();
  lblTitle.setText("N/A");
  lblYear = new Label();
  lblYear.setText("N/A");
  imgCover = new ImageView();
  imgCover.setImage(new Image(
    getClass().getResourceAsStream("images/album.png")));

  Reflection reflection = new Reflection();
  reflection.setFraction(0.6);
  imgCover.setFitWidth(150);
  imgCover.setPreserveRatio(true);
  imgCover.setSmooth(true);
  imgCover.setEffect(reflection);
   
  GridPane gridpane = new GridPane();
  gridpane.setPadding(new Insets(10));
  gridpane.setHgap(20);
  gridpane.add(imgCover, 0, 0, 1, GridPane.REMAINING);
  gridpane.add(lblTitle, 1, 0);
  gridpane.add(lblAlbum, 1, 1);
  gridpane.add(lblArtist, 1, 2);
  gridpane.add(lblComposer, 1, 3);
  gridpane.add(lblGenre, 1, 4);
  gridpane.add(lblYear, 1, 5);
  gridpane.add(lblDurations, 1, 6);
  
  ColumnConstraints column1 = new ColumnConstraints();
  ColumnConstraints column2 = new ColumnConstraints();
  column2.setHgrow(Priority.ALWAYS);
  gridpane.getColumnConstraints().addAll(column1, column2);
  
  RowConstraints row1 = new RowConstraints();
  row1.setValignment(VPos.TOP);
  gridpane.getRowConstraints().addAll(
    row1, row1, row1, row1, row1, row1, row1);
  
  BorderPane borderpane = new BorderPane();
  borderpane.setLeft(gridpane);
  
  return borderpane;
}  


【執行結果】
請參考以下範例處理影像媒體的Metadata資料,程式與上述範例幾乎一樣,只是兩者所處理的Metadata標籤資料不同而已。此外,影像媒體並沒有image的Metadata標籤,但為與上述範例一致,因此亦加入圖像。須注意的是JavaFX僅支援FLV與FXM影像。

【執行結果】
【參考資料】

[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,深入研究Java Swing。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 2.2 API Specification.
[6] Java Platform, Standard Edition 7 API Specification.

© Chia-Hui Huang 

沒有留言:

張貼留言