Révision 3197

tmp/org.txm.backtomedia.feature/feature.xml (revision 3197)
46 46
      <import plugin="org.txm.concordance.core" version="1.0.0" match="greaterOrEqual"/>
47 47
      <import plugin="org.txm.concordance.rcp" version="1.0.0" match="greaterOrEqual"/>
48 48
      <import plugin="org.txm.edition.rcp" version="1.0.0" match="greaterOrEqual"/>
49
      <import plugin="org.txm.libs.javafx" version="1.0.0" match="greaterOrEqual"/>
50 49
   </requires>
51 50

  
52 51
   <plugin
tmp/org.txm.backtomedia.rcp/JFXPlayer.java (revision 3197)
1
package org.txm.backtomedia.editors.player;
2

  
3
import java.io.File;
4
import java.net.Authenticator;
5
import java.net.PasswordAuthentication;
6
import java.time.LocalTime;
7
import java.time.format.DateTimeFormatter;
8
import java.util.concurrent.Semaphore;
9

  
10
import org.eclipse.swt.SWT;
11
import org.eclipse.swt.events.MouseEvent;
12
import org.eclipse.swt.events.MouseListener;
13
import org.eclipse.swt.events.SelectionEvent;
14
import org.eclipse.swt.events.SelectionListener;
15
import org.eclipse.swt.graphics.Point;
16
import org.eclipse.swt.layout.GridData;
17
import org.eclipse.swt.layout.GridLayout;
18
import org.eclipse.swt.widgets.Button;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.Event;
21
import org.eclipse.swt.widgets.FileDialog;
22
import org.eclipse.swt.widgets.Label;
23
import org.eclipse.swt.widgets.Listener;
24
import org.eclipse.swt.widgets.Scale;
25
import org.txm.backtomedia.commands.function.TripleRangeSlider;
26
import org.txm.backtomedia.preferences.BackToMediaPreferences;
27
import org.txm.utils.logger.Log;
28

  
29
import javafx.application.Platform;
30
import javafx.beans.InvalidationListener;
31
import javafx.beans.Observable;
32
import javafx.embed.swt.FXCanvas;
33
import javafx.geometry.Insets;
34
import javafx.scene.Group;
35
import javafx.scene.Scene;
36
import javafx.scene.layout.HBox;
37
import javafx.scene.media.Media;
38
import javafx.scene.media.MediaPlayer;
39
import javafx.scene.media.MediaPlayer.Status;
40
import javafx.scene.media.MediaView;
41
import javafx.scene.paint.Color;
42
import javafx.util.Duration;
43
import vlcplayerrcp.MessagesMP;
44

  
45
public class JFXPlayer extends Composite implements IPlayer {
46
	
47
	protected static final String NOMEDIA = ""; //$NON-NLS-1$
48
	
49
	private MediaPlayer jfxPlayer;
50
	
51
	//private GLComposite videoComposite;
52
	
53
	private Scale rateField;
54
	
55
	private Label rateValueLabel;
56
	
57
	private Scale volumeField;
58
	
59
	private Label volumeValueLabel;
60
	
61
	private Button playButton;
62
	
63
	private Button repeatButton;
64
	
65
	protected String currentlyPlayed = ""; //$NON-NLS-1$
66
	
67
	// private String startTime, endTime;
68
	private int start, end;
69
	
70
	protected boolean hasEnded = false;
71
	
72
	private String previouslyPlayed = ""; //$NON-NLS-1$
73
	
74
	private boolean repeat = false;
75
	
76
	protected int volume = 100;
77
	
78
	private Button stopButton;
79
	
80
	Label timeLabel;
81
	
82
	TripleRangeSlider timeRange;
83
	
84
	boolean firstLengthEvent = true;
85
	
86
	long previous = 0;
87
	
88
	long time, mins, secs;
89
	
90
	public MediaPlayer getEmbeddedMediaPlayer() {
91
		return jfxPlayer;
92
	}
93
	
94
	Semaphore s = new Semaphore(1);
95
	
96
	private FXCanvas fxCanvas;
97
	
98
	Point previousP;
99
	
100
	protected boolean userStopped;
101
	
102
	public JFXPlayer(Composite parent, int style) {
103
		super(parent, style);
104
		this.setLayout(new GridLayout(11, false));
105
		
106
		// very important to avoid error when re-opening the player
107
		javafx.application.Platform.setImplicitExit(false);
108
		
109
		// THE PLAYER
110
		// if (RuntimeUtil.isMac()) {
111
		// try {
112
		// LibC.INSTANCE.setenv("VLC_PLUGIN_PATH", "/Applications/VLC.app/Contents/MacOS/plugins", 1);
113
		// }
114
		// catch (Exception ex) {
115
		// ex.printStackTrace();
116
		// }
117
		// }
118
//		videoComposite = new GLComposite(this, SWT.NONE, "Video");
119
//		GridData gdata = new GridData(SWT.FILL, SWT.FILL, true, true);
120
//		gdata.horizontalSpan = 11;
121
//		videoComposite.setLayoutData(gdata);
122
//		jfxPlayer = null;
123
//		
124
//		fxCanvas.addDisposeListener(new DisposeListener() {
125
//			
126
//			@Override
127
//			public void widgetDisposed(DisposeEvent e) {
128
//				if (jfxPlayer != null) {
129
//					jfxPlayer.dispose();
130
//					jfxPlayer = null;
131
//					fxCanvas.setScene(null);
132
//				}
133
//			}
134
//		});
135
		
136
		fxCanvas = new FXCanvas(this, SWT.BORDER);
137
		GridData gdata2 = new GridData(SWT.FILL, SWT.FILL, true, true);
138
		gdata2.horizontalSpan = 11;
139

  
140
		fxCanvas.setLayoutData(gdata2);
141
		
142
		fxCanvas.addMouseListener(new MouseListener() {
143
			
144
			@Override
145
			public void mouseUp(MouseEvent e) {
146
				if (jfxPlayer != null) {
147
					if (jfxPlayer.getStatus().equals(Status.PAUSED)) {
148
						resume();
149
					}
150
					else if (jfxPlayer.getStatus().equals(Status.PLAYING)) {
151
						pause();
152
					}
153
				}
154
			}
155
			
156
			@Override
157
			public void mouseDown(MouseEvent e) {}
158
			
159
			@Override
160
			public void mouseDoubleClick(MouseEvent e) {}
161
		});
162
		
163
		fxCanvas.addListener(SWT.Resize, new Listener() {
164
			
165
			@Override
166
			public void handleEvent(Event e) {
167
				resizeView();
168
			}
169
		});
170
		
171
		// THE CONTROL BUTTONS
172
		playButton = new Button(this, SWT.PUSH);
173
		GridData playLayoutData = new GridData(SWT.FILL, SWT.CENTER, false, false);
174
		playButton.setLayoutData(playLayoutData);
175
		playButton.setText(MessagesMP.play);
176
		playButton.addSelectionListener(new SelectionListener() {
177
			
178
			@Override
179
			public void widgetSelected(SelectionEvent e) {
180
				userStopped = false;
181
				if (currentlyPlayed.length() == 0) {
182
					selectMedia();
183
					playButton.setText(MessagesMP.pause);
184
					playButton.getParent().layout();
185
				}
186
				else if (jfxPlayer != null && jfxPlayer.getStatus().equals(Status.PLAYING)) {
187
					pause();
188
				}
189
				else if (jfxPlayer != null && hasEnded) {
190
					if (jfxPlayer == null) return;
191
					replay();
192
				}
193
				else {
194
					resume();
195
				}
196
			}
197
			
198
			@Override
199
			public void widgetDefaultSelected(SelectionEvent e) {}
200
		});
201
		
202
		// Button browseButton = new Button(this,SWT.PUSH);
203
		// browseButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
204
		// browseButton.setText("Open...");
205
		// browseButton.addSelectionListener(new SelectionListener() {
206
		// @Override
207
		// public void widgetSelected(SelectionEvent e) {
208
		// selectMedia();
209
		// }
210
		//
211
		// @Override
212
		// public void widgetDefaultSelected(SelectionEvent e) {}
213
		// });
214
		
215
		stopButton = new Button(this, SWT.PUSH);
216
		stopButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
217
		stopButton.setText(MessagesMP.stop);
218
		stopButton.addSelectionListener(new SelectionListener() {
219
			
220
			@Override
221
			public void widgetSelected(SelectionEvent e) {
222
				if (jfxPlayer != null) {
223
					userStopped = true;
224
					jfxPlayer.stop();
225
				}
226
			}
227
			
228
			@Override
229
			public void widgetDefaultSelected(SelectionEvent e) {}
230
		});
231
		
232
		timeLabel = new Label(this, SWT.NONE);
233
		timeLabel.setText("00:00"); //$NON-NLS-1$
234
		
235
		timeRange = new TripleRangeSlider(this, SWT.None);
236
		timeRange.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
237
		timeRange.setToolTipText(MessagesMP.time_range);
238
		timeRange.addSelectionListener(new SelectionListener() {
239
			
240
			@Override
241
			public void widgetSelected(SelectionEvent e) {
242
				TripleRangeSlider.SELECTED_KNOB sk = timeRange.getLastSelectedKnob();
243
				switch (sk) {
244
					case UPPER:
245
						end = timeRange.getUpperValue();
246
						
247
						jfxPlayer.setStopTime(Duration.seconds(end));
248
						if (end < time) {
249
							// System.out.println("Upper changed: fix time");
250
							time = end;
251
							jfxPlayer.seek(Duration.seconds(time));
252
						}
253
						break;
254
					case LOWER:
255
						start = timeRange.getLowerValue();
256
						jfxPlayer.setStartTime(Duration.seconds(start));
257
						if (start > time) {
258
							// System.out.println("Lower changed: fix time");
259
							time = start;
260
							jfxPlayer.seek(Duration.seconds(time));
261
						}
262
						break;
263
					case MIDDLE:
264
						
265
						time = timeRange.getMiddleValue();
266
						// System.out.println("Middle changed: fix time: " + time);
267
						
268
						jfxPlayer.seek(Duration.seconds(time));
269
						
270
						break;
271
					default:
272
						// nothing
273
				}
274
				// System.out.println("time range: "+start+" -> "+end+" time="+time);
275
			}
276
			
277
			@Override
278
			public void widgetDefaultSelected(SelectionEvent e) {}
279
		});
280
		
281
		repeatButton = new Button(this, SWT.CHECK);
282
		repeatButton.setText(MessagesMP.repeat);
283
		repeat = BackToMediaPreferences.getInstance().getBoolean(BackToMediaPreferences.REPEAT);
284
		repeatButton.setSelection(repeat);
285
		repeatButton.addSelectionListener(new SelectionListener() {
286
			
287
			@Override
288
			public void widgetSelected(SelectionEvent e) {
289
				repeat = repeatButton.getSelection();
290
			}
291
			
292
			@Override
293
			public void widgetDefaultSelected(SelectionEvent e) {}
294
		});
295
		
296
		Label l = new Label(this, SWT.NONE);
297
		l.setText(MessagesMP.rate);
298
		
299
		rateField = new Scale(this, SWT.BORDER);
300
		GridData gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
301
		gdata4.widthHint = 100;
302
		rateField.setLayoutData(gdata4);
303
		rateField.setMaximum(140);
304
		rateField.setMinimum(70);
305
		rateField.setSelection(100);
306
		rateField.setPageIncrement(5);
307
		
308
		rateField.addSelectionListener(new SelectionListener() {
309
			
310
			@Override
311
			public void widgetSelected(SelectionEvent e) {
312
				float rate = rateField.getSelection() / 100.0f;
313
				jfxPlayer.setRate(rate);
314
				rateValueLabel.setText("" + rateField.getSelection() + "%");
315
			}
316
			
317
			@Override
318
			public void widgetDefaultSelected(SelectionEvent e) {}
319
		});
320
		
321
		rateValueLabel = new Label(this, SWT.NONE);
322
		rateValueLabel.setText("100%");//$NON-NLS-1$
323
		
324
		l = new Label(this, SWT.NONE);
325
		l.setText(MessagesMP.volume);
326
		
327
		volumeField = new Scale(this, SWT.BORDER);
328
		gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
329
		gdata4.widthHint = 100;
330
		volumeField.setLayoutData(gdata4);
331
		volumeField.setMinimum(0);
332
		volumeField.setMaximum(100);
333
		volumeField.setSelection(volume);
334
		volumeField.setPageIncrement(5);
335
		volumeField.addSelectionListener(new SelectionListener() {
336
			
337
			@Override
338
			public void widgetSelected(SelectionEvent e) {
339
				jfxPlayer.setVolume(volumeField.getSelection());
340
				volume = volumeField.getSelection();
341
				volumeValueLabel.setText("" + volume + "%");
342
			}
343
			
344
			@Override
345
			public void widgetDefaultSelected(SelectionEvent e) {}
346
		});
347
		
348
		volumeValueLabel = new Label(this, SWT.NONE);
349
		volumeValueLabel.setText("100%");
350
		
351
		// vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
352
		//
353
		// @Override
354
		// public void opening(MediaPlayer mediaPlayer) {
355
		// if (videoComposite.isDisposed()) return;
356
		// Log.finer("Opening media...");
357
		// }
358
		//
359
		// @Override
360
		// public void finished(MediaPlayer mediaPlayer) {
361
		// if (videoComposite.isDisposed()) return;
362
		// Log.finer("Finished playing media...");
363
		// if (repeat) {
364
		// replay();
365
		// }
366
		// else {
367
		// hasEnded = true;
368
		// }
369
		// }
370
		// });
371
		
372
		
373
		//
374
		// vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
375
		//
376
		// @Override
377
		// public void timeChanged(MediaPlayer mediaPlayer, final long arg1) {
378
		//
379
		// }
380
		//
381
		// @Override
382
		// public void lengthChanged(MediaPlayer mediaPlayer, final long arg1) {
383
		// if (videoComposite.isDisposed()) return;
384
		//
385
		// if (firstLengthEvent) {
386
		// firstLengthEvent = false;
387
		//
388
		// // initialize time range widget limits
389
		// timeRange.getDisplay().syncExec(new Runnable() {
390
		//
391
		// @Override
392
		// public void run() {
393
		// if (timeRange.isDisposed()) return;
394
		// timeRange.setMaximum((int) arg1);
395
		// // if (start == end) end = (int)arg1;
396
		//
397
		// if (end > 0 && start != end) {
398
		// timeRange.setUpperValue(end);
399
		// }
400
		// else {
401
		// timeRange.setUpperValue((int) arg1);
402
		// }
403
		//
404
		// timeRange.setLowerValue(start);
405
		// // System.out.println("Range: "+start+" -> "+end+" song length "+arg1);
406
		// }
407
		// });
408
		// }
409
		// }
410
		// });
411
	}
412
	
413
	protected void resizeView() {
414
		if (view != null) {
415
			Point p = fxCanvas.getSize();
416
			// if (previousP == null || (p.x != previousP.x && p.y != previousP.y)) { // ensure size changed
417
			view.setFitHeight(p.y);
418
			view.setFitWidth(p.x);
419
			previousP = p;
420
			// }
421
		}
422
	}
423
	
424
	public void resume() {
425
		if (jfxPlayer != null) {
426
			jfxPlayer.play();
427
			playButton.setText(MessagesMP.pause);
428
			playButton.getParent().layout();
429
		}
430
	}
431
	
432
	public void pause() {
433
		if (jfxPlayer != null) {
434
			jfxPlayer.pause();
435
			playButton.setText(MessagesMP.resume);
436
			playButton.getParent().layout();
437
		}
438
	}
439
	
440
	private void updateTimeLabel() {
441
		mins = time / 60;
442
		secs = (time) % 60;
443
		timeLabel.setText(String.format("%02d:%02d", mins, secs)); //$NON-NLS-1$
444
		timeLabel.update();
445
	}
446
	
447
	public void replay() {
448
		if (currentlyPlayed.length() > 0) {
449
			jfxPlayer.seek(Duration.seconds(start));
450
			playButton.setText(MessagesMP.pause);
451
			playButton.getParent().layout();
452
		}
453
	}
454
	
455
	protected void selectMedia() {
456
		Log.fine(MessagesMP.select_file);
457
		
458
		FileDialog fd = new FileDialog(JFXPlayer.this.getShell(), SWT.OPEN);
459
		fd.setText(MessagesMP.select_file_title);
460
		File f = new File(previouslyPlayed);
461
		if (f.isDirectory()) fd.setFilterPath(f.getPath());
462
		else fd.setFilterPath(f.getParent());
463
		
464
		String[] filterExt = { "*.*", "*.mp3", "*.mp4", "*.avi", "*.ogg", "*.ogv" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
465
		fd.setFilterExtensions(filterExt);
466
		String selected = fd.open();
467
		if (selected == null) {
468
			System.out.println(MessagesMP.cancel);
469
			return;
470
		}
471
		
472
		currentlyPlayed = selected;
473
		previouslyPlayed = selected;
474
		Log.fine(MessagesMP.opening + currentlyPlayed);
475
		play(new File(currentlyPlayed).toURI().toString(), 0, 0);
476
	}
477
	
478
	/**
479
	 * 
480
	 * @param mrl
481
	 * @param time msec start time
482
	 * @param endtime msec end time
483
	 */
484
	@Override
485
	public boolean play(String mrl, int time, int endtime) {
486
		Log.fine(MessagesMP.bind(MessagesMP.playing, new Object[] { mrl, time, endtime }));
487
		return play(mrl, "" + time, "" + endtime); //$NON-NLS-1$ //$NON-NLS-2$
488
	}
489
	
490
	@Override
491
	public boolean play(String mrl, int time) {
492
		return play(mrl, time, time);
493
	}
494
	
495
	public void hideStopButton() {
496
		if (this.stopButton != null && !this.stopButton.isDisposed()) {
497
			this.stopButton.dispose();
498
		}
499
	}
500
	
501
	DateTimeFormatter hhmmssFormatter = DateTimeFormatter.ISO_LOCAL_TIME;
502
	
503
	private MediaView view;
504
	
505
	private Group group;
506
	
507
	private Scene scene;
508
	
509
	private String mrl;
510
	
511
	private Media media;
512
	
513
	@Override
514
	public final void setCredentials(String login, String mdp) {
515
		Authenticator.setDefault(new Authenticator() {
516
			
517
			@Override
518
			public PasswordAuthentication getPasswordAuthentication() {
519
				// System.out.println("PA: login=" + login + " mdp=" + mdp + " mrl=" + mrl + " req=" + getRequestingHost());
520
				if (login != null && mdp != null && mrl.contains("://" + getRequestingHost() + "/")) {
521
					return new PasswordAuthentication(login, mdp.toCharArray());
522
				}
523
				return null;
524
			}
525
		});
526
	}
527
	
528
	/**
529
	 * 
530
	 * @param mrl
531
	 * @param startTime "0.0" or ""hh:mm:ss" format
532
	 * @param endTime "0.0" or ""hh:mm:ss" format
533
	 */
534
	@Override
535
	public boolean play(String mrl, String startTime, String endTime) {
536
		
537
		if (mrl.contains("{0}:{1}@")) {
538
			mrl = mrl.replace("{0}:{1}@", "");
539
		}
540
		
541
		this.mrl = mrl;
542
		if (startTime.matches("[0-9]+.[0-9]+")) {
543
			start = (int) (Float.parseFloat(startTime));
544
		}
545
		else if (startTime.matches("[0-9]+:[0-9]+:[0-9]+")) {
546
			if (startTime.indexOf(":") == 1) {
547
				startTime = "0" + startTime;
548
			}
549
			LocalTime time1 = LocalTime.parse(startTime, hhmmssFormatter);
550
			start = ((time1.getHour() * 60 * 60) + (time1.getMinute() * 60) + time1.getSecond());
551
		}
552
		
553
		if (endTime.matches("[0-9]+.[0-9]+")) {
554
			end = (int) (Float.parseFloat(endTime));
555
		}
556
		else if (endTime.matches("[0-9]+:[0-9]+:[0-9]+")) {
557
			if (endTime.indexOf(":") == 1) endTime = "0" + endTime;
558
			LocalTime time1 = LocalTime.parse(endTime, hhmmssFormatter);
559
			end = ((time1.getHour() * 60 * 60) + (time1.getMinute() * 60) + time1.getSecond());
560
		}
561
		
562
		// if (start == end) end = -1;
563
		
564
		Log.finer(MessagesMP.bind(MessagesMP.playing, new Object[] { mrl, startTime, endTime }));
565
		// vlcPlayer.submit(new Runnable() {
566
		//
567
		// @Override
568
		// public void run() {
569
		// String[] options = { " :live-caching=200" }; // reduce video stream cache duration to 200ms
570
		
571
		Log.finer("Preparing media...");
572
		try {
573
			javafx.application.Platform.runLater(new Runnable() {
574
				
575
				@Override
576
				public void run() {
577
					Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
578
						
579
						@Override
580
						public void uncaughtException(Thread t, Throwable e) {
581
							System.out.println("JavaFX uncaught exception: " + e);
582
						}
583
					});
584
				}
585
			});
586
			media = new Media(mrl);
587
			if (jfxPlayer != null) {
588
				try {
589
					jfxPlayer.stop();
590
				}
591
				catch (Exception e) {
592
					
593
				}
594
			}
595
			
596
			Platform.setImplicitExit(false); // This is important to avoid Thread exception when re-opening a player
597
			jfxPlayer = new MediaPlayer(media);
598
			
599
			if (jfxPlayer.getError() == null) {
600
				jfxPlayer.setOnError(new Runnable() {
601
					
602
					@Override
603
					public void run() {
604
						System.out.println("JFX Player Error:");
605
						jfxPlayer.getError().printStackTrace();
606
					}
607
				});
608
			}
609
			else {
610
				System.out.println("Warning: could not retrieve media error logger");
611
			}
612
			
613
			//initializePlayerListeners();
614
			jfxPlayer.setAutoPlay(false);
615
			
616
			view = new MediaView(jfxPlayer);
617
			
618
			HBox buttonSection = new HBox(view);
619
		    buttonSection.setPadding(new Insets(2));
620
			group = new Group(buttonSection);
621
			//group.setAutoSizeChildren(true);
622
			// scene = new Scene(group, Color.rgb(fxCanvas.getBackground().getRed(), fxCanvas.getBackground().getGreen(), fxCanvas.getBackground().getBlue()));
623
			scene = new Scene(group, Color.rgb(0, 0, 0));
624
			
625
			fxCanvas.setScene(scene);
626
			
627
			//view.setPreserveRatio(true);
628
		}
629
		catch (Exception e) {
630
			e.printStackTrace();
631
			return false;
632
		}
633
		
634
		jfxPlayer.setOnReady(new Runnable() {
635
			
636
			@Override
637
			public void run() {
638
				
639
				timeRange.setMinimum(0);
640
				Duration d = jfxPlayer.getMedia().getDuration();
641
				if (d.toSeconds() > 0) {
642
					timeRange.setMaximum((int) d.toSeconds());
643
				}
644
				timeRange.setLowerValue(start);
645
				timeRange.setMiddleValue(start);
646
				
647
				jfxPlayer.setVolume(volume);
648
				
649
				jfxPlayer.setStartTime(Duration.seconds(start));
650
				//jfxPlayer.seek(Duration.seconds(start));
651
				if (end > start) {
652
					timeRange.setUpperValue(end);
653
					jfxPlayer.setStopTime(Duration.seconds(end));
654
				}
655
				else if (d.toSeconds() > 0) {
656
					timeRange.setUpperValue((int) jfxPlayer.getMedia().getDuration().toSeconds());
657
				}
658
				Log.info("Playing media: "+media.getSource());
659
				
660
				jfxPlayer.play();
661
				//resizeView();
662
				
663
				// if (new File(mrl + ".srt").exists()) { //$NON-NLS-1$
664
				// vlcPlayer.sub.subpictures().setSubTitleFile(mrl + ".srt"); //$NON-NLS-1$
665
				// }
666
				currentlyPlayed = JFXPlayer.this.mrl;
667
				previouslyPlayed = JFXPlayer.this.mrl;
668
				
669
				if (!playButton.isDisposed()) {
670
					playButton.setText(MessagesMP.pause);
671
					playButton.getParent().layout(true);
672
				}
673
				firstLengthEvent = true;
674
			}
675
		});
676
		
677
		return true;
678
	}
679
	
680
	private void initializePlayerListeners() {
681
		
682
		jfxPlayer.currentTimeProperty().addListener(new InvalidationListener() {
683
			
684
			@Override
685
			public void invalidated(Observable ov) {
686
				if (fxCanvas.isDisposed()) return;
687
				if (jfxPlayer == null) return;
688
				
689
				Duration currentTime = jfxPlayer.getCurrentTime();
690
				time = (int) currentTime.toSeconds();
691
				if (previous == time) {
692
					return;
693
				}
694
				previous = time;
695
				
696
				timeLabel.getDisplay().syncExec(new Runnable() {
697
					
698
					@Override
699
					public void run() {
700
						if (timeRange.isDisposed()) {
701
							return;
702
						}
703
						if (!timeRange.isDragMiddleKnob()) {
704
							timeRange.setMiddleValue((int) time);
705
						}
706
						updateTimeLabel();
707
						
708
						// if (time >= end && end != start) {
709
						// if (repeat) {
710
						// vlcPlayer.seek(Duration.seconds(start));
711
						// }
712
						// else {
713
						// vlcPlayer.stop();
714
						// }
715
						// }
716
					}
717
				});
718
			}
719
		});
720
	}
721
	
722
	@Override
723
	public void setRepeat(boolean repeat) {
724
		this.repeat = repeat;
725
		if (this.repeat) {
726
			jfxPlayer.setCycleCount(Integer.MAX_VALUE);
727
		}
728
		else {
729
			jfxPlayer.setCycleCount(0);
730
		}
731
		if (!repeatButton.isDisposed()) {
732
			repeatButton.setSelection(repeat);
733
		}
734
	}
735
	
736
	@Override
737
	public void stop() {
738
		if (jfxPlayer == null) return; // nothing to do
739
		
740
		
741
		userStopped = true;
742
		jfxPlayer.stop();
743
		
744
		jfxPlayer.dispose();
745
		jfxPlayer = null;
746
		if (!fxCanvas.isDisposed()) {
747
			fxCanvas.setScene(null);
748
		}
749
		currentlyPlayed = NOMEDIA;
750
		if (!playButton.isDisposed()) {
751
			playButton.setText(MessagesMP.play);
752
			playButton.getParent().layout();
753
		}
754
	}
755
	
756
	@Override
757
	public boolean isMediaLoaded() {
758
		return jfxPlayer != null && jfxPlayer.getStatus().equals(Status.READY);
759
	}
760

  
761
	@Override
762
	public void seek(float time) {
763
		
764
		this.jfxPlayer.seek(Duration.seconds(time));
765
	}
766

  
767
	@Override
768
	public void setVolume(double volume) {
769
		
770
		this.jfxPlayer.setVolume(volume);
771
	}
772

  
773
	@Override
774
	public void setRate(float rate) {
775
		
776
		this.jfxPlayer.setRate(rate);
777
	}
778

  
779
	@Override
780
	public boolean isPlaying() {
781
		
782
		return jfxPlayer.getStatus().equals(Status.PLAYING);
783
	}
784

  
785
	@Override
786
	public void setStartTime(float seconds) {
787
		
788
		this.jfxPlayer.setStartTime(Duration.seconds(seconds));
789
		
790
	}
791

  
792
	@Override
793
	public void setStopTime(float seconds) {
794
		
795
		this.jfxPlayer.setStopTime(Duration.seconds(seconds));
796
		
797
	}
798

  
799
}
0 800

  
tmp/org.txm.backtomedia.rcp/src/org/txm/backtomedia/editors/player/JFXPlayer.java (revision 3197)
1
package org.txm.backtomedia.editors.player;
2

  
3
import java.io.File;
4
import java.net.Authenticator;
5
import java.net.PasswordAuthentication;
6
import java.time.LocalTime;
7
import java.time.format.DateTimeFormatter;
8
import java.util.concurrent.Semaphore;
9

  
10
import org.eclipse.swt.SWT;
11
import org.eclipse.swt.events.MouseEvent;
12
import org.eclipse.swt.events.MouseListener;
13
import org.eclipse.swt.events.SelectionEvent;
14
import org.eclipse.swt.events.SelectionListener;
15
import org.eclipse.swt.graphics.Point;
16
import org.eclipse.swt.layout.GridData;
17
import org.eclipse.swt.layout.GridLayout;
18
import org.eclipse.swt.widgets.Button;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.Event;
21
import org.eclipse.swt.widgets.FileDialog;
22
import org.eclipse.swt.widgets.Label;
23
import org.eclipse.swt.widgets.Listener;
24
import org.eclipse.swt.widgets.Scale;
25
import org.txm.backtomedia.commands.function.TripleRangeSlider;
26
import org.txm.backtomedia.preferences.BackToMediaPreferences;
27
import org.txm.utils.logger.Log;
28

  
29
import javafx.application.Platform;
30
import javafx.beans.InvalidationListener;
31
import javafx.beans.Observable;
32
import javafx.embed.swt.FXCanvas;
33
import javafx.geometry.Insets;
34
import javafx.scene.Group;
35
import javafx.scene.Scene;
36
import javafx.scene.layout.HBox;
37
import javafx.scene.media.Media;
38
import javafx.scene.media.MediaPlayer;
39
import javafx.scene.media.MediaPlayer.Status;
40
import javafx.scene.media.MediaView;
41
import javafx.scene.paint.Color;
42
import javafx.util.Duration;
43
import vlcplayerrcp.MessagesMP;
44

  
45
public class JFXPlayer extends Composite implements IPlayer {
46
	
47
	protected static final String NOMEDIA = ""; //$NON-NLS-1$
48
	
49
	private MediaPlayer jfxPlayer;
50
	
51
	//private GLComposite videoComposite;
52
	
53
	private Scale rateField;
54
	
55
	private Label rateValueLabel;
56
	
57
	private Scale volumeField;
58
	
59
	private Label volumeValueLabel;
60
	
61
	private Button playButton;
62
	
63
	private Button repeatButton;
64
	
65
	protected String currentlyPlayed = ""; //$NON-NLS-1$
66
	
67
	// private String startTime, endTime;
68
	private int start, end;
69
	
70
	protected boolean hasEnded = false;
71
	
72
	private String previouslyPlayed = ""; //$NON-NLS-1$
73
	
74
	private boolean repeat = false;
75
	
76
	protected int volume = 100;
77
	
78
	private Button stopButton;
79
	
80
	Label timeLabel;
81
	
82
	TripleRangeSlider timeRange;
83
	
84
	boolean firstLengthEvent = true;
85
	
86
	long previous = 0;
87
	
88
	long time, mins, secs;
89
	
90
	public MediaPlayer getEmbeddedMediaPlayer() {
91
		return jfxPlayer;
92
	}
93
	
94
	Semaphore s = new Semaphore(1);
95
	
96
	private FXCanvas fxCanvas;
97
	
98
	Point previousP;
99
	
100
	protected boolean userStopped;
101
	
102
	public JFXPlayer(Composite parent, int style) {
103
		super(parent, style);
104
		this.setLayout(new GridLayout(11, false));
105
		
106
		// very important to avoid error when re-opening the player
107
		javafx.application.Platform.setImplicitExit(false);
108
		
109
		// THE PLAYER
110
		// if (RuntimeUtil.isMac()) {
111
		// try {
112
		// LibC.INSTANCE.setenv("VLC_PLUGIN_PATH", "/Applications/VLC.app/Contents/MacOS/plugins", 1);
113
		// }
114
		// catch (Exception ex) {
115
		// ex.printStackTrace();
116
		// }
117
		// }
118
//		videoComposite = new GLComposite(this, SWT.NONE, "Video");
119
//		GridData gdata = new GridData(SWT.FILL, SWT.FILL, true, true);
120
//		gdata.horizontalSpan = 11;
121
//		videoComposite.setLayoutData(gdata);
122
//		jfxPlayer = null;
123
//		
124
//		fxCanvas.addDisposeListener(new DisposeListener() {
125
//			
126
//			@Override
127
//			public void widgetDisposed(DisposeEvent e) {
128
//				if (jfxPlayer != null) {
129
//					jfxPlayer.dispose();
130
//					jfxPlayer = null;
131
//					fxCanvas.setScene(null);
132
//				}
133
//			}
134
//		});
135
		
136
		fxCanvas = new FXCanvas(this, SWT.BORDER);
137
		GridData gdata2 = new GridData(SWT.FILL, SWT.FILL, true, true);
138
		gdata2.horizontalSpan = 11;
139

  
140
		fxCanvas.setLayoutData(gdata2);
141
		
142
		fxCanvas.addMouseListener(new MouseListener() {
143
			
144
			@Override
145
			public void mouseUp(MouseEvent e) {
146
				if (jfxPlayer != null) {
147
					if (jfxPlayer.getStatus().equals(Status.PAUSED)) {
148
						resume();
149
					}
150
					else if (jfxPlayer.getStatus().equals(Status.PLAYING)) {
151
						pause();
152
					}
153
				}
154
			}
155
			
156
			@Override
157
			public void mouseDown(MouseEvent e) {}
158
			
159
			@Override
160
			public void mouseDoubleClick(MouseEvent e) {}
161
		});
162
		
163
		fxCanvas.addListener(SWT.Resize, new Listener() {
164
			
165
			@Override
166
			public void handleEvent(Event e) {
167
				resizeView();
168
			}
169
		});
170
		
171
		// THE CONTROL BUTTONS
172
		playButton = new Button(this, SWT.PUSH);
173
		GridData playLayoutData = new GridData(SWT.FILL, SWT.CENTER, false, false);
174
		playButton.setLayoutData(playLayoutData);
175
		playButton.setText(MessagesMP.play);
176
		playButton.addSelectionListener(new SelectionListener() {
177
			
178
			@Override
179
			public void widgetSelected(SelectionEvent e) {
180
				userStopped = false;
181
				if (currentlyPlayed.length() == 0) {
182
					selectMedia();
183
					playButton.setText(MessagesMP.pause);
184
					playButton.getParent().layout();
185
				}
186
				else if (jfxPlayer != null && jfxPlayer.getStatus().equals(Status.PLAYING)) {
187
					pause();
188
				}
189
				else if (jfxPlayer != null && hasEnded) {
190
					if (jfxPlayer == null) return;
191
					replay();
192
				}
193
				else {
194
					resume();
195
				}
196
			}
197
			
198
			@Override
199
			public void widgetDefaultSelected(SelectionEvent e) {}
200
		});
201
		
202
		// Button browseButton = new Button(this,SWT.PUSH);
203
		// browseButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
204
		// browseButton.setText("Open...");
205
		// browseButton.addSelectionListener(new SelectionListener() {
206
		// @Override
207
		// public void widgetSelected(SelectionEvent e) {
208
		// selectMedia();
209
		// }
210
		//
211
		// @Override
212
		// public void widgetDefaultSelected(SelectionEvent e) {}
213
		// });
214
		
215
		stopButton = new Button(this, SWT.PUSH);
216
		stopButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
217
		stopButton.setText(MessagesMP.stop);
218
		stopButton.addSelectionListener(new SelectionListener() {
219
			
220
			@Override
221
			public void widgetSelected(SelectionEvent e) {
222
				if (jfxPlayer != null) {
223
					userStopped = true;
224
					jfxPlayer.stop();
225
				}
226
			}
227
			
228
			@Override
229
			public void widgetDefaultSelected(SelectionEvent e) {}
230
		});
231
		
232
		timeLabel = new Label(this, SWT.NONE);
233
		timeLabel.setText("00:00"); //$NON-NLS-1$
234
		
235
		timeRange = new TripleRangeSlider(this, SWT.None);
236
		timeRange.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
237
		timeRange.setToolTipText(MessagesMP.time_range);
238
		timeRange.addSelectionListener(new SelectionListener() {
239
			
240
			@Override
241
			public void widgetSelected(SelectionEvent e) {
242
				TripleRangeSlider.SELECTED_KNOB sk = timeRange.getLastSelectedKnob();
243
				switch (sk) {
244
					case UPPER:
245
						end = timeRange.getUpperValue();
246
						
247
						jfxPlayer.setStopTime(Duration.seconds(end));
248
						if (end < time) {
249
							// System.out.println("Upper changed: fix time");
250
							time = end;
251
							jfxPlayer.seek(Duration.seconds(time));
252
						}
253
						break;
254
					case LOWER:
255
						start = timeRange.getLowerValue();
256
						jfxPlayer.setStartTime(Duration.seconds(start));
257
						if (start > time) {
258
							// System.out.println("Lower changed: fix time");
259
							time = start;
260
							jfxPlayer.seek(Duration.seconds(time));
261
						}
262
						break;
263
					case MIDDLE:
264
						
265
						time = timeRange.getMiddleValue();
266
						// System.out.println("Middle changed: fix time: " + time);
267
						
268
						jfxPlayer.seek(Duration.seconds(time));
269
						
270
						break;
271
					default:
272
						// nothing
273
				}
274
				// System.out.println("time range: "+start+" -> "+end+" time="+time);
275
			}
276
			
277
			@Override
278
			public void widgetDefaultSelected(SelectionEvent e) {}
279
		});
280
		
281
		repeatButton = new Button(this, SWT.CHECK);
282
		repeatButton.setText(MessagesMP.repeat);
283
		repeat = BackToMediaPreferences.getInstance().getBoolean(BackToMediaPreferences.REPEAT);
284
		repeatButton.setSelection(repeat);
285
		repeatButton.addSelectionListener(new SelectionListener() {
286
			
287
			@Override
288
			public void widgetSelected(SelectionEvent e) {
289
				repeat = repeatButton.getSelection();
290
			}
291
			
292
			@Override
293
			public void widgetDefaultSelected(SelectionEvent e) {}
294
		});
295
		
296
		Label l = new Label(this, SWT.NONE);
297
		l.setText(MessagesMP.rate);
298
		
299
		rateField = new Scale(this, SWT.BORDER);
300
		GridData gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
301
		gdata4.widthHint = 100;
302
		rateField.setLayoutData(gdata4);
303
		rateField.setMaximum(140);
304
		rateField.setMinimum(70);
305
		rateField.setSelection(100);
306
		rateField.setPageIncrement(5);
307
		
308
		rateField.addSelectionListener(new SelectionListener() {
309
			
310
			@Override
311
			public void widgetSelected(SelectionEvent e) {
312
				float rate = rateField.getSelection() / 100.0f;
313
				jfxPlayer.setRate(rate);
314
				rateValueLabel.setText("" + rateField.getSelection() + "%");
315
			}
316
			
317
			@Override
318
			public void widgetDefaultSelected(SelectionEvent e) {}
319
		});
320
		
321
		rateValueLabel = new Label(this, SWT.NONE);
322
		rateValueLabel.setText("100%");//$NON-NLS-1$
323
		
324
		l = new Label(this, SWT.NONE);
325
		l.setText(MessagesMP.volume);
326
		
327
		volumeField = new Scale(this, SWT.BORDER);
328
		gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
329
		gdata4.widthHint = 100;
330
		volumeField.setLayoutData(gdata4);
331
		volumeField.setMinimum(0);
332
		volumeField.setMaximum(100);
333
		volumeField.setSelection(volume);
334
		volumeField.setPageIncrement(5);
335
		volumeField.addSelectionListener(new SelectionListener() {
336
			
337
			@Override
338
			public void widgetSelected(SelectionEvent e) {
339
				jfxPlayer.setVolume(volumeField.getSelection());
340
				volume = volumeField.getSelection();
341
				volumeValueLabel.setText("" + volume + "%");
342
			}
343
			
344
			@Override
345
			public void widgetDefaultSelected(SelectionEvent e) {}
346
		});
347
		
348
		volumeValueLabel = new Label(this, SWT.NONE);
349
		volumeValueLabel.setText("100%");
350
		
351
		// vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
352
		//
353
		// @Override
354
		// public void opening(MediaPlayer mediaPlayer) {
355
		// if (videoComposite.isDisposed()) return;
356
		// Log.finer("Opening media...");
357
		// }
358
		//
359
		// @Override
360
		// public void finished(MediaPlayer mediaPlayer) {
361
		// if (videoComposite.isDisposed()) return;
362
		// Log.finer("Finished playing media...");
363
		// if (repeat) {
364
		// replay();
365
		// }
366
		// else {
367
		// hasEnded = true;
368
		// }
369
		// }
370
		// });
371
		
372
		
373
		//
374
		// vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
375
		//
376
		// @Override
377
		// public void timeChanged(MediaPlayer mediaPlayer, final long arg1) {
378
		//
379
		// }
380
		//
381
		// @Override
382
		// public void lengthChanged(MediaPlayer mediaPlayer, final long arg1) {
383
		// if (videoComposite.isDisposed()) return;
384
		//
385
		// if (firstLengthEvent) {
386
		// firstLengthEvent = false;
387
		//
388
		// // initialize time range widget limits
389
		// timeRange.getDisplay().syncExec(new Runnable() {
390
		//
391
		// @Override
392
		// public void run() {
393
		// if (timeRange.isDisposed()) return;
394
		// timeRange.setMaximum((int) arg1);
395
		// // if (start == end) end = (int)arg1;
396
		//
397
		// if (end > 0 && start != end) {
398
		// timeRange.setUpperValue(end);
399
		// }
400
		// else {
401
		// timeRange.setUpperValue((int) arg1);
402
		// }
403
		//
404
		// timeRange.setLowerValue(start);
405
		// // System.out.println("Range: "+start+" -> "+end+" song length "+arg1);
406
		// }
407
		// });
408
		// }
409
		// }
410
		// });
411
	}
412
	
413
	protected void resizeView() {
414
		if (view != null) {
415
			Point p = fxCanvas.getSize();
416
			// if (previousP == null || (p.x != previousP.x && p.y != previousP.y)) { // ensure size changed
417
			view.setFitHeight(p.y);
418
			view.setFitWidth(p.x);
419
			previousP = p;
420
			// }
421
		}
422
	}
423
	
424
	public void resume() {
425
		if (jfxPlayer != null) {
426
			jfxPlayer.play();
427
			playButton.setText(MessagesMP.pause);
428
			playButton.getParent().layout();
429
		}
430
	}
431
	
432
	public void pause() {
433
		if (jfxPlayer != null) {
434
			jfxPlayer.pause();
435
			playButton.setText(MessagesMP.resume);
436
			playButton.getParent().layout();
437
		}
438
	}
439
	
440
	private void updateTimeLabel() {
441
		mins = time / 60;
442
		secs = (time) % 60;
443
		timeLabel.setText(String.format("%02d:%02d", mins, secs)); //$NON-NLS-1$
444
		timeLabel.update();
445
	}
446
	
447
	public void replay() {
448
		if (currentlyPlayed.length() > 0) {
449
			jfxPlayer.seek(Duration.seconds(start));
450
			playButton.setText(MessagesMP.pause);
451
			playButton.getParent().layout();
452
		}
453
	}
454
	
455
	protected void selectMedia() {
456
		Log.fine(MessagesMP.select_file);
457
		
458
		FileDialog fd = new FileDialog(JFXPlayer.this.getShell(), SWT.OPEN);
459
		fd.setText(MessagesMP.select_file_title);
460
		File f = new File(previouslyPlayed);
461
		if (f.isDirectory()) fd.setFilterPath(f.getPath());
462
		else fd.setFilterPath(f.getParent());
463
		
464
		String[] filterExt = { "*.*", "*.mp3", "*.mp4", "*.avi", "*.ogg", "*.ogv" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
465
		fd.setFilterExtensions(filterExt);
466
		String selected = fd.open();
467
		if (selected == null) {
468
			System.out.println(MessagesMP.cancel);
469
			return;
470
		}
471
		
472
		currentlyPlayed = selected;
473
		previouslyPlayed = selected;
474
		Log.fine(MessagesMP.opening + currentlyPlayed);
475
		play(new File(currentlyPlayed).toURI().toString(), 0, 0);
476
	}
477
	
478
	/**
479
	 * 
480
	 * @param mrl
481
	 * @param time msec start time
482
	 * @param endtime msec end time
483
	 */
484
	@Override
485
	public boolean play(String mrl, int time, int endtime) {
486
		Log.fine(MessagesMP.bind(MessagesMP.playing, new Object[] { mrl, time, endtime }));
487
		return play(mrl, "" + time, "" + endtime); //$NON-NLS-1$ //$NON-NLS-2$
488
	}
489
	
490
	@Override
491
	public boolean play(String mrl, int time) {
492
		return play(mrl, time, time);
493
	}
494
	
495
	public void hideStopButton() {
496
		if (this.stopButton != null && !this.stopButton.isDisposed()) {
497
			this.stopButton.dispose();
498
		}
499
	}
500
	
501
	DateTimeFormatter hhmmssFormatter = DateTimeFormatter.ISO_LOCAL_TIME;
502
	
503
	private MediaView view;
504
	
505
	private Group group;
506
	
507
	private Scene scene;
508
	
509
	private String mrl;
510
	
511
	private Media media;
512
	
513
	@Override
514
	public final void setCredentials(String login, String mdp) {
515
		Authenticator.setDefault(new Authenticator() {
516
			
517
			@Override
518
			public PasswordAuthentication getPasswordAuthentication() {
519
				// System.out.println("PA: login=" + login + " mdp=" + mdp + " mrl=" + mrl + " req=" + getRequestingHost());
520
				if (login != null && mdp != null && mrl.contains("://" + getRequestingHost() + "/")) {
521
					return new PasswordAuthentication(login, mdp.toCharArray());
522
				}
523
				return null;
524
			}
525
		});
526
	}
527
	
528
	/**
529
	 * 
530
	 * @param mrl
531
	 * @param startTime "0.0" or ""hh:mm:ss" format
532
	 * @param endTime "0.0" or ""hh:mm:ss" format
533
	 */
534
	@Override
535
	public boolean play(String mrl, String startTime, String endTime) {
536
		
537
		if (mrl.contains("{0}:{1}@")) {
538
			mrl = mrl.replace("{0}:{1}@", "");
539
		}
540
		
541
		this.mrl = mrl;
542
		if (startTime.matches("[0-9]+.[0-9]+")) {
543
			start = (int) (Float.parseFloat(startTime));
544
		}
545
		else if (startTime.matches("[0-9]+:[0-9]+:[0-9]+")) {
546
			if (startTime.indexOf(":") == 1) {
547
				startTime = "0" + startTime;
548
			}
549
			LocalTime time1 = LocalTime.parse(startTime, hhmmssFormatter);
550
			start = ((time1.getHour() * 60 * 60) + (time1.getMinute() * 60) + time1.getSecond());
551
		}
552
		
553
		if (endTime.matches("[0-9]+.[0-9]+")) {
554
			end = (int) (Float.parseFloat(endTime));
555
		}
556
		else if (endTime.matches("[0-9]+:[0-9]+:[0-9]+")) {
557
			if (endTime.indexOf(":") == 1) endTime = "0" + endTime;
558
			LocalTime time1 = LocalTime.parse(endTime, hhmmssFormatter);
559
			end = ((time1.getHour() * 60 * 60) + (time1.getMinute() * 60) + time1.getSecond());
560
		}
561
		
562
		// if (start == end) end = -1;
563
		
564
		Log.finer(MessagesMP.bind(MessagesMP.playing, new Object[] { mrl, startTime, endTime }));
565
		// vlcPlayer.submit(new Runnable() {
566
		//
567
		// @Override
568
		// public void run() {
569
		// String[] options = { " :live-caching=200" }; // reduce video stream cache duration to 200ms
570
		
571
		Log.finer("Preparing media...");
572
		try {
573
			javafx.application.Platform.runLater(new Runnable() {
574
				
575
				@Override
576
				public void run() {
577
					Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
578
						
579
						@Override
580
						public void uncaughtException(Thread t, Throwable e) {
581
							System.out.println("JavaFX uncaught exception: " + e);
582
						}
583
					});
584
				}
585
			});
586
			media = new Media(mrl);
587
			if (jfxPlayer != null) {
588
				try {
589
					jfxPlayer.stop();
590
				}
591
				catch (Exception e) {
592
					
593
				}
594
			}
595
			
596
			Platform.setImplicitExit(false); // This is important to avoid Thread exception when re-opening a player
597
			jfxPlayer = new MediaPlayer(media);
598
			
599
			if (jfxPlayer.getError() == null) {
600
				jfxPlayer.setOnError(new Runnable() {
601
					
602
					@Override
603
					public void run() {
604
						System.out.println("JFX Player Error:");
605
						jfxPlayer.getError().printStackTrace();
606
					}
607
				});
608
			}
609
			else {
610
				System.out.println("Warning: could not retrieve media error logger");
611
			}
612
			
613
			//initializePlayerListeners();
614
			jfxPlayer.setAutoPlay(false);
615
			
616
			view = new MediaView(jfxPlayer);
617
			
618
			HBox buttonSection = new HBox(view);
619
		    buttonSection.setPadding(new Insets(2));
620
			group = new Group(buttonSection);
621
			//group.setAutoSizeChildren(true);
622
			// scene = new Scene(group, Color.rgb(fxCanvas.getBackground().getRed(), fxCanvas.getBackground().getGreen(), fxCanvas.getBackground().getBlue()));
623
			scene = new Scene(group, Color.rgb(0, 0, 0));
624
			
625
			fxCanvas.setScene(scene);
626
			
627
			//view.setPreserveRatio(true);
628
		}
629
		catch (Exception e) {
630
			e.printStackTrace();
631
			return false;
632
		}
633
		
634
		jfxPlayer.setOnReady(new Runnable() {
635
			
636
			@Override
637
			public void run() {
638
				
639
				timeRange.setMinimum(0);
640
				Duration d = jfxPlayer.getMedia().getDuration();
641
				if (d.toSeconds() > 0) {
642
					timeRange.setMaximum((int) d.toSeconds());
643
				}
644
				timeRange.setLowerValue(start);
645
				timeRange.setMiddleValue(start);
646
				
647
				jfxPlayer.setVolume(volume);
648
				
649
				jfxPlayer.setStartTime(Duration.seconds(start));
650
				//jfxPlayer.seek(Duration.seconds(start));
651
				if (end > start) {
652
					timeRange.setUpperValue(end);
653
					jfxPlayer.setStopTime(Duration.seconds(end));
654
				}
655
				else if (d.toSeconds() > 0) {
656
					timeRange.setUpperValue((int) jfxPlayer.getMedia().getDuration().toSeconds());
657
				}
658
				Log.info("Playing media: "+media.getSource());
659
				
660
				jfxPlayer.play();
661
				//resizeView();
662
				
663
				// if (new File(mrl + ".srt").exists()) { //$NON-NLS-1$
664
				// vlcPlayer.sub.subpictures().setSubTitleFile(mrl + ".srt"); //$NON-NLS-1$
665
				// }
666
				currentlyPlayed = JFXPlayer.this.mrl;
667
				previouslyPlayed = JFXPlayer.this.mrl;
668
				
669
				if (!playButton.isDisposed()) {
670
					playButton.setText(MessagesMP.pause);
671
					playButton.getParent().layout(true);
672
				}
673
				firstLengthEvent = true;
674
			}
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff