Quando si lavora sui contenuti audio/video può essere utile inserire delle label su specifici istanti temporali lungo la linea di riproduzione del media. Ad esempio potremmo voler visualizzare un URL o un messaggio quando raggiungiamo un specifico momento durante la riproduzione del video.
I marker sono questo, semplici stringhe di testo, utilizzabili per i più svariati compiti, associati a istanti temporali.
Un player pronto all'uso
Riprendiamo il nostro semplice video player con i due pulsanti play e stop e arricchito dalla gestione degli errori e dalla riproduzione in modalità tracking:
public class FxMediaExample extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws MalformedURLException {
URL mediaUrl = new URL("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
Media media = new Media(mediaUrl.toExternalForm());
MediaPlayer player = new MediaPlayer(media);
player.setAutoPlay(false);
player.setStartTime(Duration.seconds(10));
player.setStopTime(Duration.seconds(20));
Button playButton = new Button("Play");
Button stopButton = new Button("Stop");
playButton.setOnAction((ActionEvent event) -> {
if (player.getStatus() == Status.PLAYING) {
player.stop();
player.play();
} else {
player.play();
}
});
stopButton.setOnAction((ActionEvent event) -> {
player.stop();
});
MediaView mediaView = new MediaView(player);
mediaView.setFitWidth(350);
mediaView.setFitHeight(200);
mediaView.setSmooth(true);
player.setOnError(() -> {
errorMessage(player.getError());
});
media.setOnError(() -> {
errorMessage(player.getError());
});
mediaView.setOnError((MediaErrorEvent event) -> {
errorMessage(event.getMediaError());
});
HBox controlBox = new HBox(5, playButton, stopButton);
VBox root = new VBox(5, mediaView, controlBox, markerMessage);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Media Player Demo");
stage.show();
}
private void errorMessage(MediaException error) {
MediaException.Type errorType = error.getType();
String errorMessage = error.getMessage();
System.out.println("Message:"+errorMessage+" Type:"+errorType);
}
}
e proseguiamo aggiungendo due marker al video: uno all'istante "5 secondi" e un altro all'istante "20 secondi".
Markers
Nella classe Media
è presente il metodo getMarkers()
con cui accedere alla mappa javafx.collections.ObservableMap
che consente l'inserimento di marker in modalità chiave-valore. Aggiungiamo i due marker inserendo le seguenti linee di codice subito dopo la definizione dell'oggetto Media
:
ObservableMap markers = media.getMarkers();
markers.put("1", Duration.seconds(5));
markers.put("2", Duration.seconds(20));
Modifichiamo leggermente il layout dell'applicativo in modo da avere una TextArea per la stampa delle stringhe dei marker appena definiti. La stampa avverrà non appena i marker verranno raggiunti dell'avanzamento della linea temporale. Subito dopo la definizione dei pulsanti di play e stop aggiungiamo:
final TextArea markerMessage = new TextArea();
markerMessage.setPrefSize(1, 2);
Inseriamo quindi la gestione degli eventi legati ai marker immediatamente dopo la definizione della gestione degli errori:
player.setOnMarker((MediaMarkerEvent event) -> {
Pair<String, Duration> marker = event.getMarker();
String key = marker.getKey();
Duration markerTime = marker.getValue();
markerMessage.appendText("Raggiunto marker "+ key + " all'istante " + markerTime+"\n");
});
Completiamo il tutto aggiornando la definizione dell'oggetto VBox root in modo tale che accetti la TextArea per la stampa degli eventi:
VBox root = new VBox(5, mediaView, controlBox, markerMessage);
Possiamo quindi eseguire l'applicativo ottenendo un risultato simile a quello mostrato nella seguente immagine. Per eseguire il video dall'inizio alla fine commentiamo le linee di codice relative al tracking.