diff --git a/teavm-samples/pom.xml b/teavm-samples/pom.xml
index 1b9dc40c4..4bef2c0be 100644
--- a/teavm-samples/pom.xml
+++ b/teavm-samples/pom.xml
@@ -32,5 +32,6 @@
teavm-samples-hello
teavm-samples-benchmark
+ teavm-samples-video
\ No newline at end of file
diff --git a/teavm-samples/teavm-samples-video/pom.xml b/teavm-samples/teavm-samples-video/pom.xml
new file mode 100644
index 000000000..351969f11
--- /dev/null
+++ b/teavm-samples/teavm-samples-video/pom.xml
@@ -0,0 +1,110 @@
+
+
+ 4.0.0
+
+
+ org.teavm
+ teavm-samples
+ 0.3.0-SNAPSHOT
+
+ teavm-samples-video
+
+ war
+
+ TeaVM HTML5 video web application
+ A sample application that shows HTML5 video implementation for TeaVM
+
+
+
+ org.teavm
+ teavm-classlib
+ ${project.version}
+
+
+ org.teavm
+ teavm-jso
+ ${project.version}
+
+
+ org.teavm
+ teavm-dom
+ ${project.version}
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ provided
+
+
+
+
+
+
+ maven-war-plugin
+ 2.4
+
+
+
+ ${project.build.directory}/generated/js
+
+
+
+
+
+ org.teavm
+ teavm-maven-plugin
+ ${project.version}
+
+
+ web-client
+ prepare-package
+
+ build-javascript
+
+
+ ${project.build.directory}/generated/js/teavm
+ org.teavm.samples.video.Player
+ SEPARATE
+ false
+ true
+ true
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+ ../../checkstyle.xml
+ config_loc=${basedir}/../..
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+
+
\ No newline at end of file
diff --git a/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java
new file mode 100644
index 000000000..c8a90d60c
--- /dev/null
+++ b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2014 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.samples.video;
+
+import org.teavm.dom.browser.Window;
+import org.teavm.dom.events.Event;
+import org.teavm.dom.events.EventListener;
+import org.teavm.dom.html.HTMLBodyElement;
+import org.teavm.dom.html.HTMLButtonElement;
+import org.teavm.dom.html.HTMLDocument;
+import org.teavm.dom.html.HTMLElement;
+import org.teavm.dom.html.HTMLSourceElement;
+import org.teavm.dom.html.HTMLVideoElement;
+import org.teavm.jso.JS;
+
+public final class Player {
+
+ private static Window window = (Window)JS.getGlobal();
+ private static HTMLDocument document = window.getDocument();
+
+ private Player() {
+ }
+
+ public static void main(String[] args) {
+ HTMLSourceElement sourceMp4 = (HTMLSourceElement)document.createElement("source");
+ sourceMp4.setAttribute("id", "mp4");
+ sourceMp4.setSrc("http://media.w3.org/2010/05/sintel/trailer.mp4");
+ sourceMp4.setAttribute("type", "video/mp4");
+
+ HTMLSourceElement sourceWebm = (HTMLSourceElement)document.createElement("source");
+ sourceWebm.setAttribute("id", "webm");
+ sourceWebm.setSrc("http://media.w3.org/2010/05/sintel/trailer.webm");
+ sourceWebm.setAttribute("type", "video/webm");
+
+ HTMLSourceElement sourceOgv = (HTMLSourceElement)document.createElement("source");
+ sourceOgv.setAttribute("id", "ogv");
+ sourceOgv.setSrc("http://media.w3.org/2010/05/sintel/trailer.ogv");
+ sourceOgv.setAttribute("type", "video/ogg");
+
+ HTMLElement p = document.createElement("p");
+ p.appendChild(document.createTextNode("Your user agent does not support the HTML5 Video element."));
+
+ final HTMLVideoElement video = (HTMLVideoElement)document.createElement("video");
+ video.setAttribute("id", "video");
+ video.setControls(true);
+ video.setPreload("none");
+ video.setMediaGroup("myVideoGroup");
+ video.setPoster("http://media.w3.org/2010/05/sintel/poster.png");
+ video.appendChild(sourceMp4);
+ video.appendChild(sourceWebm);
+ video.appendChild(sourceOgv);
+ video.appendChild(p);
+
+ HTMLElement divVideo = document.createElement("div");
+ divVideo.appendChild(video);
+
+ HTMLButtonElement loadButton = (HTMLButtonElement)document.createElement("button");
+ loadButton.appendChild(document.createTextNode("load()"));
+ loadButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.load();
+ }
+ });
+
+ HTMLButtonElement playButton = (HTMLButtonElement)document.createElement("button");
+ playButton.appendChild(document.createTextNode("play()"));
+ playButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.play();
+ }
+ });
+
+ HTMLButtonElement pauseButton = (HTMLButtonElement)document.createElement("button");
+ pauseButton.appendChild(document.createTextNode("pause()"));
+ pauseButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.pause();
+ }
+ });
+
+ HTMLButtonElement currentTimePlusButton = (HTMLButtonElement)document.createElement("button");
+ currentTimePlusButton.appendChild(document.createTextNode("currentTime+=10"));
+ currentTimePlusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setCurrentTime(video.getController().getCurrentTime() + 10);
+ }
+ });
+
+ HTMLButtonElement currentTimeMinusButton = (HTMLButtonElement)document.createElement("button");
+ currentTimeMinusButton.appendChild(document.createTextNode("currentTime-=10"));
+ currentTimeMinusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setCurrentTime(video.getController().getCurrentTime() - 10);
+ }
+ });
+
+ HTMLButtonElement currentTime50Button = (HTMLButtonElement)document.createElement("button");
+ currentTime50Button.appendChild(document.createTextNode("currentTime=50"));
+ currentTime50Button.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setCurrentTime(50);
+ }
+ });
+
+ HTMLButtonElement playbackRateIncrementButton = (HTMLButtonElement)document.createElement("button");
+ playbackRateIncrementButton.appendChild(document.createTextNode("playbackRate++"));
+ playbackRateIncrementButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setPlaybackRate(video.getController().getPlaybackRate() + 1);
+ }
+ });
+
+ HTMLButtonElement playbackRateDecrementButton = (HTMLButtonElement)document.createElement("button");
+ playbackRateDecrementButton.appendChild(document.createTextNode("playbackRate--"));
+ playbackRateDecrementButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setPlaybackRate(video.getController().getPlaybackRate() - 1);
+ }
+ });
+
+ HTMLButtonElement playbackRatePlusButton = (HTMLButtonElement)document.createElement("button");
+ playbackRatePlusButton.appendChild(document.createTextNode("playbackRate+=0.1"));
+ playbackRatePlusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setPlaybackRate(video.getController().getPlaybackRate() + 0.1);
+ }
+ });
+
+ HTMLButtonElement playbackRateMinusButton = (HTMLButtonElement)document.createElement("button");
+ playbackRateMinusButton.appendChild(document.createTextNode("playbackRate-=0.1"));
+ playbackRateMinusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setPlaybackRate(video.getController().getPlaybackRate() - 0.1);
+ }
+ });
+
+ HTMLButtonElement volumePlusButton = (HTMLButtonElement)document.createElement("button");
+ volumePlusButton.appendChild(document.createTextNode("volume+=0.1"));
+ volumePlusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setVolume(video.getController().getVolume() + 0.1f);
+ }
+ });
+
+ HTMLButtonElement volumeMinusButton = (HTMLButtonElement)document.createElement("button");
+ volumeMinusButton.appendChild(document.createTextNode("volume-=0.1"));
+ volumeMinusButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setVolume(video.getController().getVolume() - 0.1f);
+ }
+ });
+
+ HTMLButtonElement muteButton = (HTMLButtonElement)document.createElement("button");
+ muteButton.appendChild(document.createTextNode("muted=true"));
+ muteButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setMuted(true);
+ }
+ });
+
+ HTMLButtonElement unmuteButton = (HTMLButtonElement)document.createElement("button");
+ unmuteButton.appendChild(document.createTextNode("muted=false"));
+ unmuteButton.addEventListener("click", new EventListener() {
+ @Override
+ public void handleEvent(Event evt) {
+ video.getController().setMuted(false);
+ }
+ });
+
+ HTMLElement divButtons = document.createElement("div");
+ divButtons.setAttribute("id", "buttons");
+ divButtons.appendChild(loadButton);
+ divButtons.appendChild(playButton);
+ divButtons.appendChild(pauseButton);
+ divButtons.appendChild(document.createElement("br"));
+ divButtons.appendChild(currentTimePlusButton);
+ divButtons.appendChild(currentTimeMinusButton);
+ divButtons.appendChild(currentTime50Button);
+ divButtons.appendChild(document.createElement("br"));
+ divButtons.appendChild(playbackRateIncrementButton);
+ divButtons.appendChild(playbackRateDecrementButton);
+ divButtons.appendChild(playbackRatePlusButton);
+ divButtons.appendChild(playbackRateMinusButton);
+ divButtons.appendChild(document.createElement("br"));
+ divButtons.appendChild(volumePlusButton);
+ divButtons.appendChild(volumeMinusButton);
+ divButtons.appendChild(muteButton);
+ divButtons.appendChild(unmuteButton);
+
+ HTMLBodyElement body = document.getBody();
+ body.appendChild(divVideo);
+ body.appendChild(divButtons);
+ }
+
+}
diff --git a/teavm-samples/teavm-samples-video/src/main/webapp/WEB-INF/web.xml b/teavm-samples/teavm-samples-video/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6471cd77a
--- /dev/null
+++ b/teavm-samples/teavm-samples-video/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+
+
+
+
\ No newline at end of file
diff --git a/teavm-samples/teavm-samples-video/src/main/webapp/index.html b/teavm-samples/teavm-samples-video/src/main/webapp/index.html
new file mode 100644
index 000000000..e9740a3fe
--- /dev/null
+++ b/teavm-samples/teavm-samples-video/src/main/webapp/index.html
@@ -0,0 +1,28 @@
+
+
+
+
+ HTML5 Video web application
+
+
+
+
+
+
+ HTML5 Video web application
+
+
\ No newline at end of file
diff --git a/teavm-samples/teavm-samples-video/src/main/webapp/style.css b/teavm-samples/teavm-samples-video/src/main/webapp/style.css
new file mode 100644
index 000000000..d84ba0e5b
--- /dev/null
+++ b/teavm-samples/teavm-samples-video/src/main/webapp/style.css
@@ -0,0 +1,12 @@
+video {
+ border: 1px solid black;
+ padding: 0; margin: 0;
+ width: 427px;
+ height: 240px;
+ background-color: black;
+ margin: auto;
+ float: left;
+}
+#buttons {
+ text-align: center;
+}
\ No newline at end of file