mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-12 05:35:31 +00:00
Working version featuring Youtube video.
- tested with a single 49 Europeans file on Firefox and Chrome - still an issue with Chrome playing sound even though everything is set to muted. --> Workaround: mute the video by choosing it in the sound track selection and then un-choose it again. - issue with Youtube player when youtube is configured to use HTML5 player instead of Flash
This commit is contained in:
1 parent
e6b42f162c
commit
bb3168ad58
16 files changed
+567
-371
No files matched your search
@@ -1,4 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
entryPointModules=
|
||||
filesCopiedToWebInfLib=gwt-servlet.jar
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVmlkZW9Qb3B1cDwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+UFJFVFRZPC9vdXRwdXQtc3R5bGU+PGV4dHJhLWFyZ3M+PCFbQ0RBVEFbLXdhciAuIC1sb2NhbFdvcmtlcnMgMyAtc3RyaWN0IC1sb2dMZXZlbCBUUkFDRV1dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14MTAyNG1dXT48L3ZtLWFyZ3M+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLkFkbWluQ29uc29sZTwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZEVkaXRpbmc8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuUmFjZUJvYXJkPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlNwZWN0YXRvcjwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5Vc2VyTWFuYWdlbWVudDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5WaWRlb1BvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLllvdXR1YmVQb3B1cDwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+
|
||||
@@ -0,0 +1,18 @@
|
||||
html {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
html,body,div,iframe {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: none;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
@@ -4,6 +4,11 @@
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>SAP Sailing Video</title>
|
||||
<script type="text/javascript" language="javascript" src="com.sap.sailing.gwt.ui.VideoPopup/com.sap.sailing.gwt.ui.VideoPopup.nocache.js"></script>
|
||||
<style type="text/css">
|
||||
html {overflow: auto;}
|
||||
html, body, div, iframe {margin: 0px; padding: 0px; height: 100%; border: none;}
|
||||
iframe {display: block; width: 100%; border: none; overflow-y: auto; overflow-x: hidden;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>SAP Sailing Video</title>
|
||||
<script type="text/javascript" language="javascript" src="com.sap.sailing.gwt.ui.YoutubePopup/com.sap.sailing.gwt.ui.YoutubePopup.nocache.js"></script>
|
||||
<style type="text/css">
|
||||
html {overflow: auto;}
|
||||
html, body, div, iframe {margin: 0px; padding: 0px; height: 100%; border: none;}
|
||||
iframe {display: block; width: 100%; border: none; overflow-y: auto; overflow-x: hidden;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -29,6 +29,11 @@ bin.includes = META-INF/,\
|
||||
Spectator.css,\
|
||||
fontface.css,\
|
||||
webfonts/,\
|
||||
com.sap.sailing.gwt.ui.VideoPopup/,\
|
||||
VideoPopup.html,\
|
||||
VideoPopup.css,\
|
||||
com.sap.sailing.gwt.ui.YoutubePopup/,\
|
||||
YoutubePopup.html,\
|
||||
TvView.html,\
|
||||
com.sap.sailing.gwt.ui.TvView/
|
||||
output.. = WEB-INF/classes/
|
||||
+3
-3
@@ -5,7 +5,7 @@ import com.google.gwt.dom.client.MediaElement;
|
||||
import com.google.gwt.media.client.Audio;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
public class AudioControl extends AbstractMediaPlayer {
|
||||
public class AudioPlayer extends AbstractMediaPlayer {
|
||||
|
||||
/**
|
||||
* isReady and the ..Cache fields are required because setting the audio element's play state
|
||||
@@ -19,7 +19,7 @@ public class AudioControl extends AbstractMediaPlayer {
|
||||
|
||||
private final Audio audio;
|
||||
|
||||
public AudioControl(MediaTrack mediaTrack) {
|
||||
public AudioPlayer(MediaTrack mediaTrack) {
|
||||
super(mediaTrack);
|
||||
audio = Audio.createIfSupported();
|
||||
if (audio != null) {
|
||||
@@ -38,7 +38,7 @@ public class AudioControl extends AbstractMediaPlayer {
|
||||
var that = this;
|
||||
audioElement.addEventListener('canplay',
|
||||
function() {
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.AudioControl::initPlayState()();
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.AudioPlayer::initPlayState()();
|
||||
});
|
||||
}-*/;
|
||||
|
||||
+17
-10
@@ -47,9 +47,9 @@ public class MediaSelectionDialog implements CloseHandler<PopupPanel> {
|
||||
Panel grid = new VerticalPanel();
|
||||
if (!audioTracks.isEmpty()) {
|
||||
grid.add(createAudioHeader());
|
||||
grid.add((RadioButton) createAudioItem(null, selectedAudioTrack));
|
||||
grid.add((RadioButton) createAudioButton(null, selectedAudioTrack));
|
||||
for (MediaTrack audioTrack : audioTracks) {
|
||||
grid.add(createAudioItem(audioTrack, selectedAudioTrack));
|
||||
grid.add(createAudioButton(audioTrack, selectedAudioTrack));
|
||||
}
|
||||
}
|
||||
if (!videoTracks.isEmpty()) {
|
||||
@@ -82,6 +82,13 @@ public class MediaSelectionDialog implements CloseHandler<PopupPanel> {
|
||||
return videoCheckBox;
|
||||
}
|
||||
|
||||
public void selectVideo(MediaTrack videoTrack) {
|
||||
CheckBox videoCheckBox = videoCheckBoxes.get(videoTrack);
|
||||
if (videoCheckBox != null) {
|
||||
videoCheckBox.setValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void unselectVideo(MediaTrack videoTrack) {
|
||||
CheckBox videoCheckBox = videoCheckBoxes.get(videoTrack);
|
||||
if (videoCheckBox != null) {
|
||||
@@ -94,13 +101,13 @@ public class MediaSelectionDialog implements CloseHandler<PopupPanel> {
|
||||
return audioHeader;
|
||||
}
|
||||
|
||||
private Widget createAudioItem(final MediaTrack audioTrack, MediaTrack selectedAudioTrack) {
|
||||
String title = audioTrack != null ? audioTrack.title: "Mute - play no sound";
|
||||
String tooltip = audioTrack != null ? audioTrack.toString() : "Play no sound.";
|
||||
RadioButton audioItem = new RadioButton("group-name", title);
|
||||
audioItem.setTitle(tooltip);
|
||||
audioItem.setValue(audioTrack == selectedAudioTrack);
|
||||
audioItem.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
private Widget createAudioButton(final MediaTrack audioTrack, MediaTrack selectedAudioTrack) {
|
||||
String title = audioTrack != null ? audioTrack.title: "Sound off";
|
||||
String tooltip = audioTrack != null ? audioTrack.toString() : "Turn off all sound channels.";
|
||||
RadioButton audioButton = new RadioButton("group-name", title);
|
||||
audioButton.setTitle(tooltip);
|
||||
audioButton.setValue(audioTrack == selectedAudioTrack);
|
||||
audioButton.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Boolean> changeEvent) {
|
||||
@@ -109,7 +116,7 @@ public class MediaSelectionDialog implements CloseHandler<PopupPanel> {
|
||||
}
|
||||
}
|
||||
});
|
||||
return audioItem;
|
||||
return audioButton;
|
||||
}
|
||||
|
||||
private Widget createAudioHeader() {
|
||||
|
||||
+41
-23
@@ -33,7 +33,7 @@ import com.sap.sailing.gwt.ui.client.TimeListener;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
|
||||
import com.sap.sailing.gwt.ui.raceboard.MediaSelectionDialog.MediaSelectionListener;
|
||||
import com.sap.sailing.gwt.ui.raceboard.VideoControl.VideoCloseListener;
|
||||
import com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer.PopupCloseListener;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
private final AudioElement mediaCanPlayTester;
|
||||
|
||||
private MediaPlayer activeAudioPlayer;
|
||||
private final Map<MediaTrack, VideoControl> videoPlayers = new HashMap<MediaTrack, VideoControl>();
|
||||
private final Map<MediaTrack, MediaPlayer> videoPlayers = new HashMap<MediaTrack, MediaPlayer>();
|
||||
private final Set<MediaTrack> audioTracks = new HashSet<MediaTrack>();
|
||||
private final Set<MediaTrack> videoTracks = new HashSet<MediaTrack>();
|
||||
private final ErrorReporter errorReporter;
|
||||
@@ -113,11 +113,15 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
|
||||
private boolean canPlay(MediaTrack mediaTrack) {
|
||||
if (mediaCanPlayTester != null) {
|
||||
String canPlay = mediaCanPlayTester.canPlayType(mediaTrack.typeToString());
|
||||
if (mediaCanPlayTester != null) {
|
||||
return MediaElement.CAN_PLAY_PROBABLY.equals(canPlay) || MediaElement.CAN_PLAY_MAYBE.equals(canPlay);
|
||||
if (mediaTrack.isYoutube()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
String canPlay = mediaCanPlayTester.canPlayType(mediaTrack.typeToString());
|
||||
if (mediaCanPlayTester != null) {
|
||||
return MediaElement.CAN_PLAY_PROBABLY.equals(canPlay) || MediaElement.CAN_PLAY_MAYBE.equals(canPlay);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -183,7 +187,7 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
if (activeAudioPlayer != null) {
|
||||
activeAudioPlayer.setPlaybackSpeed(this.currentPlaybackSpeed);
|
||||
}
|
||||
for (VideoControl videoPlayer : videoPlayers.values()) {
|
||||
for (MediaPlayer videoPlayer : videoPlayers.values()) {
|
||||
videoPlayer.setPlaybackSpeed(this.currentPlaybackSpeed);
|
||||
}
|
||||
}
|
||||
@@ -258,7 +262,7 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
|
||||
@Override
|
||||
public void audioChanged(MediaTrack audioTrack) {
|
||||
if (activeAudioPlayer != null) {
|
||||
if (activeAudioPlayer != null) { // --> then reset active audio player
|
||||
|
||||
if (activeAudioPlayer.getMediaTrack() == audioTrack) {
|
||||
return; //nothing changed
|
||||
@@ -266,12 +270,16 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
|
||||
if (videoPlayers.containsKey(activeAudioPlayer.getMediaTrack())) { //pre-change audioPlayer is one of the videoPlayers
|
||||
activeAudioPlayer.setMuted(true);
|
||||
} else {//pre-change audioPlayer is a dedicated audio-only player
|
||||
} else { //pre-change audioPlayer is a dedicated audio-only player
|
||||
activeAudioPlayer.destroy();
|
||||
}
|
||||
activeAudioPlayer = null;
|
||||
}
|
||||
VideoControl playingVideo = videoPlayers.get(audioTrack);
|
||||
if ((audioTrack != null) && audioTrack.isYoutube()) { // --> Youtube videos can't be played for audio-only. So add a video player first.
|
||||
videoSelected(audioTrack);
|
||||
mediaSelectionDialog.selectVideo(audioTrack);
|
||||
}
|
||||
MediaPlayer playingVideo = videoPlayers.get(audioTrack);
|
||||
if (playingVideo != null) {
|
||||
activeAudioPlayer = playingVideo;
|
||||
activeAudioPlayer.setMuted(false);
|
||||
@@ -285,23 +293,29 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
|
||||
@Override
|
||||
public void videoSelected(final MediaTrack videoTrack) {
|
||||
VideoControl playingVideo = videoPlayers.get(videoTrack);
|
||||
MediaPlayer playingVideo = videoPlayers.get(videoTrack);
|
||||
if (playingVideo == null) {
|
||||
final VideoControl videoControl = new VideoControl(videoTrack, new VideoCloseListener() {
|
||||
PopupCloseListener popCloseListener = new PopupCloseListener() {
|
||||
@Override
|
||||
public void onVideoClosed() {
|
||||
public void popupClosed() {
|
||||
videoDeselected(videoTrack);
|
||||
}
|
||||
});
|
||||
videoPlayers.put(videoTrack, videoControl);
|
||||
};
|
||||
final PopupWindowPlayer popupPlayer;
|
||||
if (videoTrack.isYoutube()) {
|
||||
popupPlayer = new YoutubeWindowPlayer(videoTrack, popCloseListener);
|
||||
} else {
|
||||
popupPlayer = new VideoWindowPlayer(videoTrack, popCloseListener);
|
||||
}
|
||||
videoPlayers.put(videoTrack, popupPlayer);
|
||||
if ((activeAudioPlayer != null) && (activeAudioPlayer.getMediaTrack() == videoTrack)) { //selected video track has been playing as audio-only
|
||||
activeAudioPlayer.pause();
|
||||
activeAudioPlayer = videoControl;
|
||||
videoControl.setMuted(false);
|
||||
activeAudioPlayer = popupPlayer;
|
||||
popupPlayer.setMuted(false);
|
||||
} else {
|
||||
videoControl.setMuted(true);
|
||||
popupPlayer.setMuted(true);
|
||||
}
|
||||
synchPlayState(videoControl);
|
||||
synchPlayState(popupPlayer);
|
||||
} else {
|
||||
//nothing changed
|
||||
}
|
||||
@@ -313,10 +327,14 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
@Override
|
||||
public void videoDeselected(MediaTrack videoTrack) {
|
||||
mediaSelectionDialog.unselectVideo(videoTrack);
|
||||
VideoControl removedVideoPlayer = videoPlayers.remove(videoTrack);
|
||||
MediaPlayer removedVideoPlayer = videoPlayers.remove(videoTrack);
|
||||
removedVideoPlayer.destroy();
|
||||
if (removedVideoPlayer == activeAudioPlayer) { //in case this video has been the sound source, replace the video player with a dedicated audio player
|
||||
assignNewAudioPlayer(removedVideoPlayer.getMediaTrack());
|
||||
if (removedVideoPlayer.getMediaTrack().isYoutube()) {
|
||||
assignNewAudioPlayer(null);
|
||||
} else {
|
||||
assignNewAudioPlayer(removedVideoPlayer.getMediaTrack());
|
||||
}
|
||||
}
|
||||
|
||||
updateToggleButton();
|
||||
@@ -329,7 +347,7 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
|
||||
private void assignNewAudioPlayer(MediaTrack audioTrack) {
|
||||
if (audioTrack != null) {
|
||||
activeAudioPlayer = new AudioControl(audioTrack);
|
||||
activeAudioPlayer = new AudioPlayer(audioTrack);
|
||||
|
||||
synchPlayState(activeAudioPlayer);
|
||||
} else {
|
||||
@@ -373,7 +391,7 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
activeAudioPlayer.destroy();
|
||||
activeAudioPlayer = null;
|
||||
}
|
||||
for (VideoControl videoControl : videoPlayers.values()) {
|
||||
for (MediaPlayer videoControl : videoPlayers.values()) {
|
||||
videoControl.destroy();
|
||||
}
|
||||
videoPlayers.clear();
|
||||
|
||||
+149
-150
@@ -1,150 +1,149 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.http.client.URL;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
public class VideoControl extends AbstractMediaPlayer {
|
||||
|
||||
interface VideoCloseListener {
|
||||
void onVideoClosed();
|
||||
}
|
||||
|
||||
private final JavaScriptObject playerWindow;
|
||||
private final VideoCloseListener videoCloseListener;
|
||||
|
||||
public VideoControl(MediaTrack mediaTrack, VideoCloseListener videoCloseListener) {
|
||||
super(mediaTrack);
|
||||
this.videoCloseListener = videoCloseListener;
|
||||
String videoUrl = getMediaTrack().url;
|
||||
String title = getMediaTrack().title;
|
||||
|
||||
String videoPlayerUrl = "/gwt/VideoPopup.html?url=" + URL.encodeQueryString(videoUrl) + "&title=" + URL.encodeQueryString(title);
|
||||
|
||||
String codesvr = Window.Location.getParameter("gwt.codesvr");
|
||||
if (codesvr != null) {
|
||||
videoPlayerUrl = videoPlayerUrl + "&gwt.codesvr=" + codesvr;
|
||||
}
|
||||
|
||||
playerWindow = openWindow(videoPlayerUrl);
|
||||
registerNativeStuff();
|
||||
}
|
||||
|
||||
native JavaScriptObject openWindow(String url) /*-{
|
||||
return $wnd.open(url, '_blank', "resizable=yes, scrollbars=no, toolbar=no, menubar=no, status=no, location=no, directories=no, personalbar=no, width=340, height=200");
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void destroy() /*-{
|
||||
var playerWindow = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!playerWindow.closed) {
|
||||
playerWindow.close();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
native JavaScriptObject registerNativeStuff() /*-{
|
||||
var that = this;
|
||||
var window = that.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
window.onbeforeunload = function() {
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.VideoControl::onClosingPopup()();
|
||||
}
|
||||
window.parent.deferredPlayState = {
|
||||
isDeferredPlaying: false,
|
||||
isDeferredMuted: true,
|
||||
deferredMediaTime: 0,
|
||||
playbackSpeed: 1
|
||||
};
|
||||
}-*/;
|
||||
|
||||
private void onClosingPopup() {
|
||||
pause();
|
||||
if (videoCloseListener != null) {
|
||||
videoCloseListener.onVideoClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public native void play() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredPlaying = true;
|
||||
} else {
|
||||
window.parent.videoPlayer.play();
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void pause() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredPlaying = false;
|
||||
} else {
|
||||
window.parent.videoPlayer.pause();
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setTime(double mediaTime) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.deferredMediaTime = mediaTime;
|
||||
} else {
|
||||
window.parent.videoPlayer.setTime(mediaTime);
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setMuted(boolean muted) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredMuted = muted;
|
||||
} else {
|
||||
window.parent.videoPlayer.setMuted(muted);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native boolean isPaused() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return !window.parent.deferredPlayState.isDeferredPlaying;
|
||||
} else {
|
||||
return window.parent.videoPlayer.isPaused();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native double getDuration() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return NaN;
|
||||
} else {
|
||||
return window.parent.videoPlayer.getDuration();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native double getTime() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return window.parent.deferredPlayState.deferredMediaTime;
|
||||
} else {
|
||||
return window.parent.videoPlayer.getTime();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setPlaybackSpeed(double playbackSpeed) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.VideoControl::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.deferredPlaybackSpeed = playbackSpeed;
|
||||
} else {
|
||||
window.parent.videoPlayer.setPlaybackSpeed(playbackSpeed);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
}
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
public abstract class PopupWindowPlayer extends AbstractMediaPlayer {
|
||||
|
||||
interface PopupCloseListener {
|
||||
void popupClosed();
|
||||
}
|
||||
|
||||
private final JavaScriptObject playerWindow;
|
||||
private final PopupCloseListener popupCloseListener;
|
||||
|
||||
protected PopupWindowPlayer(MediaTrack mediaTrack, PopupCloseListener popupCloseListener) {
|
||||
super(mediaTrack);
|
||||
this.popupCloseListener = popupCloseListener;
|
||||
|
||||
String playerWindowUrl = getPlayerWindowUrl();
|
||||
|
||||
String codesvr = Window.Location.getParameter("gwt.codesvr");
|
||||
if (codesvr != null) {
|
||||
playerWindowUrl = playerWindowUrl + "&gwt.codesvr=" + codesvr;
|
||||
}
|
||||
|
||||
playerWindow = openWindow(playerWindowUrl);
|
||||
registerNativeStuff();
|
||||
}
|
||||
|
||||
protected abstract String getPlayerWindowUrl();
|
||||
|
||||
native JavaScriptObject openWindow(String url) /*-{
|
||||
return $wnd.open(url, '_blank', "resizable=yes, scrollbars=no, toolbar=no, menubar=no, status=no, location=no, directories=no, personalbar=no, width=660, height=380");
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void destroy() /*-{
|
||||
var playerWindow = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!playerWindow.closed) {
|
||||
playerWindow.close();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
native JavaScriptObject registerNativeStuff() /*-{
|
||||
var that = this;
|
||||
var window = that.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
window.onbeforeunload = function() {
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::onClosingPopup()();
|
||||
}
|
||||
window.parent.deferredPlayState = {
|
||||
isDeferredPlaying: false,
|
||||
isDeferredMuted: true,
|
||||
deferredMediaTime: 0,
|
||||
playbackSpeed: 1
|
||||
};
|
||||
}-*/;
|
||||
|
||||
private void onClosingPopup() {
|
||||
pause();
|
||||
if (popupCloseListener != null) {
|
||||
popupCloseListener.popupClosed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public native void play() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredPlaying = true;
|
||||
} else {
|
||||
window.parent.videoPlayer.play();
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void pause() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredPlaying = false;
|
||||
} else {
|
||||
window.parent.videoPlayer.pause();
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setTime(double mediaTime) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.deferredMediaTime = mediaTime;
|
||||
} else {
|
||||
window.parent.videoPlayer.setTime(mediaTime);
|
||||
}
|
||||
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setMuted(boolean muted) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.isDeferredMuted = muted;
|
||||
} else {
|
||||
window.parent.videoPlayer.setMuted(muted);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native boolean isPaused() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return !window.parent.deferredPlayState.isDeferredPlaying;
|
||||
} else {
|
||||
return window.parent.videoPlayer.isPaused();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native double getDuration() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return NaN;
|
||||
} else {
|
||||
return window.parent.videoPlayer.getDuration();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native double getTime() /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
return window.parent.deferredPlayState.deferredMediaTime;
|
||||
} else {
|
||||
return window.parent.videoPlayer.getTime();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public native void setPlaybackSpeed(double playbackSpeed) /*-{
|
||||
var window = this.@com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer::playerWindow;
|
||||
if (!window.parent.videoPlayer) {
|
||||
window.parent.deferredPlayState.deferredPlaybackSpeed = playbackSpeed;
|
||||
} else {
|
||||
window.parent.videoPlayer.setPlaybackSpeed(playbackSpeed);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.http.client.URL;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
public class VideoWindowPlayer extends PopupWindowPlayer {
|
||||
|
||||
public VideoWindowPlayer(MediaTrack mediaTrack, PopupCloseListener popCloseListener) {
|
||||
super(mediaTrack, popCloseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPlayerWindowUrl() {
|
||||
String videoUrl = getMediaTrack().url;
|
||||
String title = getMediaTrack().title;
|
||||
|
||||
String videoPlayerUrl = "/gwt/VideoPopup.html?url=" + URL.encodeQueryString(videoUrl) + "&title=" + URL.encodeQueryString(title);
|
||||
|
||||
return videoPlayerUrl;
|
||||
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.http.client.URL;
|
||||
import com.sap.sailing.gwt.ui.shared.media.MediaTrack;
|
||||
|
||||
public class YoutubeWindowPlayer extends PopupWindowPlayer {
|
||||
|
||||
public YoutubeWindowPlayer(MediaTrack mediaTrack, PopupCloseListener popupCloseListener) {
|
||||
super(mediaTrack, popupCloseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPlayerWindowUrl() {
|
||||
String youtubeId = getMediaTrack().url;
|
||||
String title = getMediaTrack().title;
|
||||
|
||||
String youtubePlayerUrl = "/gwt/YoutubePopup.html?id=" + URL.encodeQueryString(youtubeId) + "&title=" + URL.encodeQueryString(title);
|
||||
|
||||
return youtubePlayerUrl;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-2
@@ -13,7 +13,7 @@ public class MediaTrack implements IsSerializable {
|
||||
|
||||
public enum MimeType {
|
||||
|
||||
mp4(MediaType.video, MediaSubType.mp4), ogv(MediaType.video, MediaSubType.ogg), qt(MediaType.video, MediaSubType.quicktime), mp3(MediaType.audio, MediaSubType.mpeg), ogg(MediaType.audio, MediaSubType.ogg), aac(MediaType.audio, MediaSubType.aac), webm(MediaType.video, MediaSubType.webm);
|
||||
mp4(MediaType.video, MediaSubType.mp4), ogv(MediaType.video, MediaSubType.ogg), qt(MediaType.video, MediaSubType.quicktime), mp3(MediaType.audio, MediaSubType.mpeg), ogg(MediaType.audio, MediaSubType.ogg), aac(MediaType.audio, MediaSubType.aac), webm(MediaType.video, MediaSubType.webm), youtube(MediaType.video, MediaSubType.youtube);
|
||||
|
||||
public final MediaType mediaType;
|
||||
public final MediaSubType mediaSubType;
|
||||
@@ -34,7 +34,7 @@ public class MediaTrack implements IsSerializable {
|
||||
}
|
||||
|
||||
public enum MediaSubType {
|
||||
ogg, mp4, mpeg, x_aiff, quicktime, aac, webm;
|
||||
ogg, mp4, mpeg, x_aiff, quicktime, aac, webm, youtube;
|
||||
|
||||
public String toString() {
|
||||
return name().replace('_', '-');
|
||||
@@ -77,5 +77,9 @@ public class MediaTrack implements IsSerializable {
|
||||
public String typeToString() {
|
||||
return mimeType == null ? "undefined" : mimeType.toString();
|
||||
}
|
||||
|
||||
public boolean isYoutube() {
|
||||
return (mimeType != null) && MediaSubType.youtube.equals(mimeType.mediaSubType);
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.sap.sailing.gwt.ui.video;
|
||||
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.user.client.Window;
|
||||
|
||||
public abstract class AbstractPopupWindow implements EntryPoint {
|
||||
|
||||
@Override
|
||||
public void onModuleLoad() {
|
||||
initializePlayer();
|
||||
}
|
||||
|
||||
protected abstract void initializePlayer();
|
||||
|
||||
native void addCallbackMethods() /*-{
|
||||
var that = this;
|
||||
$wnd.videoPlayer = {
|
||||
play : function() {
|
||||
that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::play()();
|
||||
},
|
||||
pause : function() {
|
||||
that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::pause()();
|
||||
},
|
||||
setTime : function(time) {
|
||||
that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::setTime(D)(time);
|
||||
},
|
||||
setMuted : function(muted) {
|
||||
that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::setMuted(Z)(muted);
|
||||
},
|
||||
isPaused : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::isPaused()();
|
||||
},
|
||||
getDuration : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::getDuration()();
|
||||
},
|
||||
getTime : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::getTime()();
|
||||
},
|
||||
setPlaybackSpeed : function(newPlaySpeedFactor) {
|
||||
that.@com.sap.sailing.gwt.ui.video.AbstractPopupWindow::setPlaybackSpeed(D)(newPlaySpeedFactor);
|
||||
}
|
||||
};
|
||||
}-*/;
|
||||
|
||||
public abstract void play();
|
||||
|
||||
public abstract void pause();
|
||||
|
||||
public abstract void setTime(double time);
|
||||
|
||||
public abstract void setMuted(boolean muted);
|
||||
|
||||
public abstract boolean isPaused();
|
||||
|
||||
public abstract double getDuration();
|
||||
|
||||
public abstract double getTime();
|
||||
|
||||
public abstract void setPlaybackSpeed(double newPlaySpeedFactor);
|
||||
|
||||
public void initPlayState(double deferredMediaTime, boolean isDeferredMuted, double deferredPlaybackSpeed,
|
||||
boolean isDeferredPlaying) {
|
||||
|
||||
addCallbackMethods();
|
||||
|
||||
setTime(deferredMediaTime);
|
||||
setMuted(isDeferredMuted);
|
||||
setPlaybackSpeed(deferredPlaybackSpeed);
|
||||
if (isDeferredPlaying) {
|
||||
play();
|
||||
} else {
|
||||
pause();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void adjustWindowSize() {
|
||||
int windowWidth = Window.getClientWidth();
|
||||
int videoWidth = getVideoWidth();
|
||||
int widthDelta = videoWidth - windowWidth;
|
||||
|
||||
int windowHeight = Window.getClientHeight();
|
||||
int videoHeight = getVideoHeight();
|
||||
int heightDelta = videoHeight - windowHeight;
|
||||
|
||||
Window.resizeBy(widthDelta, heightDelta);
|
||||
}
|
||||
|
||||
protected abstract boolean hasVideoSizes();
|
||||
|
||||
protected abstract int getVideoWidth();
|
||||
|
||||
protected abstract int getVideoHeight();
|
||||
|
||||
protected abstract void setVideoSize(int width, int height);
|
||||
|
||||
}
|
||||
+51
-124
@@ -1,27 +1,21 @@
|
||||
package com.sap.sailing.gwt.ui.video;
|
||||
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.dom.client.MediaElement;
|
||||
import com.google.gwt.dom.client.VideoElement;
|
||||
import com.google.gwt.event.dom.client.ContextMenuEvent;
|
||||
import com.google.gwt.event.dom.client.ContextMenuHandler;
|
||||
import com.google.gwt.event.logical.shared.ResizeEvent;
|
||||
import com.google.gwt.event.logical.shared.ResizeHandler;
|
||||
import com.google.gwt.media.client.Video;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
|
||||
public class VideoPopupWindow implements EntryPoint, ResizeHandler, ContextMenuHandler {
|
||||
public class VideoPopupWindow extends AbstractPopupWindow implements ContextMenuHandler {
|
||||
|
||||
private Video video;
|
||||
private boolean isDebug;
|
||||
|
||||
@Override
|
||||
public void onModuleLoad() {
|
||||
|
||||
Window.addResizeHandler(this);
|
||||
protected void initializePlayer() {
|
||||
|
||||
RootLayoutPanel mainPanel = RootLayoutPanel.get();
|
||||
|
||||
@@ -69,135 +63,48 @@ public class VideoPopupWindow implements EntryPoint, ResizeHandler, ContextMenuH
|
||||
});
|
||||
}-*/;
|
||||
|
||||
native void addCallbackMethods() /*-{
|
||||
var that = this;
|
||||
$wnd.videoPlayer = {
|
||||
play : function() {
|
||||
that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::play()();
|
||||
},
|
||||
pause : function() {
|
||||
that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::pause()();
|
||||
},
|
||||
setTime : function(time) {
|
||||
that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::setTime(D)(time);
|
||||
},
|
||||
setMuted : function(muted) {
|
||||
that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::setMuted(Z)(muted);
|
||||
},
|
||||
isPaused : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::isPaused()();
|
||||
},
|
||||
getDuration : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::getDuration()();
|
||||
},
|
||||
getTime : function() {
|
||||
return that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::getTime()();
|
||||
},
|
||||
setPlaybackSpeed : function(newPlaySpeedFactor) {
|
||||
that.@com.sap.sailing.gwt.ui.video.VideoPopupWindow::setPlaybackSpeed(D)(newPlaySpeedFactor);
|
||||
}
|
||||
};
|
||||
}-*/;
|
||||
|
||||
public void play() {
|
||||
video.play();
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
video.pause();
|
||||
}
|
||||
|
||||
public void setTime(double time) {
|
||||
video.setCurrentTime(time);
|
||||
}
|
||||
|
||||
public void setMuted(boolean muted) {
|
||||
video.setMuted(muted);
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return video.isPaused();
|
||||
}
|
||||
|
||||
public double getDuration() {
|
||||
return video.getDuration();
|
||||
}
|
||||
|
||||
public double getTime() {
|
||||
return video.getCurrentTime();
|
||||
}
|
||||
|
||||
public void setPlaybackSpeed(double newPlaySpeedFactor) {
|
||||
video.setPlaybackRate(newPlaySpeedFactor);
|
||||
}
|
||||
|
||||
public void loadedmetadata() {
|
||||
adjustWindowSize();
|
||||
}
|
||||
|
||||
public void initPlayState(double deferredMediaTime, boolean isDeferredMuted, double deferredPlaybackSpeed,
|
||||
boolean isDeferredPlaying) {
|
||||
|
||||
addCallbackMethods();
|
||||
|
||||
setTime(deferredMediaTime);
|
||||
setMuted(isDeferredMuted);
|
||||
setPlaybackSpeed(deferredPlaybackSpeed);
|
||||
if (isDeferredPlaying) {
|
||||
play();
|
||||
} else {
|
||||
pause();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void adjustWindowSize() {
|
||||
int clientWidth = Window.getClientWidth();
|
||||
int videoWidth = video.getVideoWidth();
|
||||
int widthDelta = videoWidth - clientWidth;
|
||||
|
||||
int clientHeight = Window.getClientHeight();
|
||||
int videoHeight = video.getVideoHeight();
|
||||
int heightDelta = videoHeight - clientHeight;
|
||||
|
||||
Window.resizeBy(widthDelta, heightDelta);
|
||||
@Override
|
||||
public void play() {
|
||||
video.play();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize(final ResizeEvent event) {
|
||||
if (video != null) {
|
||||
new Timer() {
|
||||
@Override
|
||||
public void run() {
|
||||
int videoWidth = video.getVideoWidth();
|
||||
if (videoWidth > 0) {
|
||||
int clientWidth = Window.getClientWidth();
|
||||
double widthResizeRatio = ((double) clientWidth) / videoWidth;
|
||||
public void pause() {
|
||||
video.pause();
|
||||
}
|
||||
|
||||
int videoHeight = video.getVideoHeight();
|
||||
if (videoHeight > 0) {
|
||||
int clientHeight = Window.getClientHeight();
|
||||
double heightResizeRatio = ((double) clientHeight) / videoHeight;
|
||||
@Override
|
||||
public void setTime(double time) {
|
||||
video.setCurrentTime(time);
|
||||
}
|
||||
|
||||
double resizeRatio = Math.min(widthResizeRatio, heightResizeRatio);
|
||||
@Override
|
||||
public void setMuted(boolean muted) {
|
||||
video.setMuted(muted);
|
||||
}
|
||||
|
||||
if (Math.abs(1.0 - resizeRatio) > 0.001) {
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return video.isPaused();
|
||||
}
|
||||
|
||||
int newVideoWidth = (int) Math.round(resizeRatio * videoWidth);
|
||||
int newVideoHeight = (int) Math.round(resizeRatio * videoHeight);
|
||||
video.setPixelSize(newVideoWidth, newVideoHeight);
|
||||
@Override
|
||||
public double getDuration() {
|
||||
return video.getDuration();
|
||||
}
|
||||
|
||||
int widthDelta = newVideoWidth - clientWidth;
|
||||
int heightDelta = newVideoHeight - clientHeight;
|
||||
@Override
|
||||
public double getTime() {
|
||||
return video.getCurrentTime();
|
||||
}
|
||||
|
||||
Window.resizeBy(widthDelta, heightDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}.schedule(100);
|
||||
}
|
||||
@Override
|
||||
public void setPlaybackSpeed(double newPlaySpeedFactor) {
|
||||
video.setPlaybackRate(newPlaySpeedFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,5 +117,25 @@ public class VideoPopupWindow implements EntryPoint, ResizeHandler, ContextMenuH
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasVideoSizes() {
|
||||
return video != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVideoWidth() {
|
||||
return video.getVideoWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVideoHeight() {
|
||||
return video.getVideoHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setVideoSize(int width, int height) {
|
||||
video.setPixelSize(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
+122
-57
@@ -1,76 +1,141 @@
|
||||
package com.sap.sailing.gwt.ui.video;
|
||||
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
|
||||
public class YoutubePopupWindow implements EntryPoint {
|
||||
public class YoutubePopupWindow extends AbstractPopupWindow {
|
||||
|
||||
private static final String VIDEO_CONTAINER_ID = "videoContainer";
|
||||
|
||||
private JavaScriptObject youtubePlayer;
|
||||
private static final String VIDEO_CONTAINER_ID = "videoContainer";
|
||||
|
||||
@Override
|
||||
public void onModuleLoad() {
|
||||
String title = Window.Location.getParameter("title");
|
||||
Window.setTitle(title);
|
||||
|
||||
RootLayoutPanel.get().getElement().setId(VIDEO_CONTAINER_ID);
|
||||
private JavaScriptObject youtubePlayer;
|
||||
|
||||
String videoUrl = Window.Location.getParameter("id");
|
||||
if (videoUrl != null) {
|
||||
loadYoutube(videoUrl, VIDEO_CONTAINER_ID);
|
||||
}
|
||||
@Override
|
||||
protected void initializePlayer() {
|
||||
String title = Window.Location.getParameter("title");
|
||||
Window.setTitle(title);
|
||||
|
||||
RootLayoutPanel.get().getElement().setId(VIDEO_CONTAINER_ID);
|
||||
|
||||
String videoUrl = Window.Location.getParameter("id");
|
||||
if (videoUrl != null) {
|
||||
loadYoutube(videoUrl, VIDEO_CONTAINER_ID);
|
||||
}
|
||||
}
|
||||
|
||||
// Inspired by https://developers.google.com/youtube/iframe_api_reference#Examples
|
||||
// See also: https://developers.google.com/youtube/js_api_reference
|
||||
// Code Playground: https://code.google.com/apis/ajax/playground/?exp=youtube#chromeless_player
|
||||
private native void loadYoutube(String videoUrl, String videoContainerId) /*-{
|
||||
|
||||
//inspired by https://developers.google.com/youtube/iframe_api_reference#Examples
|
||||
private native void loadYoutube(String videoUrl, String videoContainerId) /*-{
|
||||
var that = this;
|
||||
|
||||
var that = this;
|
||||
|
||||
var tag = $doc.createElement('script');
|
||||
// This is a protocol-relative URL as described here: http://paulirish.com/2010/the-protocol-relative-url/
|
||||
var tag = $doc.createElement('script');
|
||||
tag.src = "//www.youtube.com/iframe_api";
|
||||
var firstScriptTag = $doc.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
|
||||
// This is a protocol-relative URL as described here:
|
||||
// http://paulirish.com/2010/the-protocol-relative-url/
|
||||
// If you're testing a local page accessed via a file:/// URL, please set tag.src to
|
||||
// "https://www.youtube.com/iframe_api" instead.
|
||||
tag.src = "//www.youtube.com/iframe_api";
|
||||
var firstScriptTag = $doc.getElementsByTagName('script')[0];
|
||||
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||||
// This function creates an <iframe> containing a YouTube player after the API code downloads.
|
||||
var player;
|
||||
$wnd.onYouTubeIframeAPIReady = function() {
|
||||
var player = new $wnd.YT.Player(videoContainerId, {
|
||||
videoId : videoUrl,
|
||||
height: '480', //see https://developers.google.com/youtube/iframe_api_reference?hl=en#Playback_quality
|
||||
width: '853',
|
||||
events: { //https://developers.google.com/youtube/iframe_api_reference?hl=en#Events
|
||||
'onReady': function(event) {
|
||||
var deferredPlayState = $wnd.deferredPlayState
|
||||
if (deferredPlayState && !$wnd.videoPlayer) {
|
||||
that.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::initPlayState(DZDZ)(deferredPlayState.deferredMediaTime, deferredPlayState.isDeferredMuted, deferredPlayState.deferredPlaybackSpeed, deferredPlayState.isDeferredPlaying);
|
||||
}
|
||||
}
|
||||
},
|
||||
playerVars : {
|
||||
'autoplay' : 0,
|
||||
'controls' : 0
|
||||
}
|
||||
});
|
||||
// player.addEventListener("onStateChange", "handleStateChange");
|
||||
that.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::setYoutubePlayer(Lcom/google/gwt/core/client/JavaScriptObject;)(player);
|
||||
}
|
||||
|
||||
// This function creates an <iframe> containing a YouTube player after the API code downloads.
|
||||
var player;
|
||||
$wnd.onYouTubeIframeAPIReady = function() {
|
||||
var player = new $wnd.YT.Player(videoContainerId, {
|
||||
videoId : videoUrl,
|
||||
playerVars : {
|
||||
'autoplay' : 0,
|
||||
'controls' : 0
|
||||
}
|
||||
});
|
||||
that.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::setYoutubePlayer(Lcom/google/gwt/core/client/JavaScriptObject;)(player);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
}-*/;
|
||||
|
||||
public void setYoutubePlayer(JavaScriptObject youtubePlayer) {
|
||||
this.youtubePlayer = youtubePlayer;
|
||||
adjustWindowSize();
|
||||
}
|
||||
public void setYoutubePlayer(JavaScriptObject youtubePlayer) {
|
||||
this.youtubePlayer = youtubePlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPlayState(double deferredMediaTime, boolean isDeferredMuted, double deferredPlaybackSpeed, boolean isDeferredPlaying) {
|
||||
adjustWindowSize();
|
||||
super.initPlayState(deferredMediaTime, isDeferredMuted, deferredPlaybackSpeed, isDeferredPlaying);
|
||||
}
|
||||
|
||||
private void adjustWindowSize() {
|
||||
RootPanel videoContainer = RootPanel.get(VIDEO_CONTAINER_ID);
|
||||
int clientWidth = Window.getClientWidth();
|
||||
int videoWidth = videoContainer.getOffsetWidth();
|
||||
int widthDelta = videoWidth - clientWidth;
|
||||
|
||||
int clientHeight = Window.getClientHeight();
|
||||
int videoHeight = videoContainer.getOffsetHeight();
|
||||
int heightDelta = videoHeight - clientHeight;
|
||||
|
||||
Window.resizeBy(widthDelta, heightDelta);
|
||||
}
|
||||
public native void play() /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
player.playVideo();
|
||||
}-*/;
|
||||
|
||||
public native void pause() /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
player.pauseVideo();
|
||||
}-*/;
|
||||
|
||||
public native void setTime(double time) /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
var allowSeekAhead = true;
|
||||
player.seekTo(time, allowSeekAhead);
|
||||
}-*/;
|
||||
|
||||
public native void setMuted(boolean muted) /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
if (muted) {
|
||||
player.mute();
|
||||
} else {
|
||||
player.unMute()
|
||||
}
|
||||
}-*/;
|
||||
|
||||
public native boolean isPaused() /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
return player.getPlayerState() == $wnd.YT.PlayerState.PAUSED;
|
||||
}-*/;
|
||||
|
||||
public native double getDuration() /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
return player.getDuration();
|
||||
}-*/;
|
||||
|
||||
public native double getTime() /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
return player.getCurrentTime();
|
||||
}-*/;
|
||||
|
||||
public native void setPlaybackSpeed(double newPlaySpeedFactor) /*-{
|
||||
var player = this.@com.sap.sailing.gwt.ui.video.YoutubePopupWindow::youtubePlayer;
|
||||
player.setPlaybackRate(newPlaySpeedFactor);
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
protected boolean hasVideoSizes() {
|
||||
return youtubePlayer != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVideoWidth() {
|
||||
return RootPanel.get(VIDEO_CONTAINER_ID).getOffsetWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVideoHeight() {
|
||||
return RootPanel.get(VIDEO_CONTAINER_ID).getOffsetHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setVideoSize(int width, int height) {
|
||||
RootPanel.get(VIDEO_CONTAINER_ID).setPixelSize(width, height);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
|
||||
<module>
|
||||
<inherits name="com.google.gwt.user.User" />
|
||||
<stylesheet src="../reset.css" />
|
||||
<stylesheet src="../VideoPopup.css" />
|
||||
<inherits name="com.google.gwt.user.User" />
|
||||
<entry-point class="com.sap.sailing.gwt.ui.video.VideoPopupWindow" />
|
||||
<extend-property name="locale" values="de"/>
|
||||
<source path='video'/>
|
||||
|
||||
Reference in new issue
Block a user