All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.components.MediaPlayer Maven / Gradle / Ivy

There is a newer version: 7.0.161
Show newest version
/*
 * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */
package com.codename1.components;

import com.codename1.io.Log;
import com.codename1.media.AsyncMedia;
import com.codename1.media.Media;
import com.codename1.media.MediaManager;
import com.codename1.ui.Button;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Image;
import com.codename1.ui.Slider;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.UITimer;
import java.io.IOException;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 

Video playback component with control buttons for back, play/pause and * forward buttons. In the simulator those controls are implemented locally but on the * device the native playback controls are used. *

* * * Media player sample * */ public class MediaPlayer extends Container { private Image playIcon; private Image pauseIcon; private Image backIcon; private Image fwdIcon; private Image maxIcon; private Container buttonsBar; private boolean hideNativeVideoControls; private boolean showControls=true; private Runnable loopOnCompletion; private Slider progress; private UITimer progressUpdater; /** * Shows the buttons on top of the video */ private boolean onTopMode = true; /** * Shows video position bar as a slider */ private boolean seekBar = true; /** * UIID for the seekBar slider */ private String seekBarUIID = null; /** * Includes a maximize icon in the bar to show the native player */ private boolean maximize = true; private boolean userSetIcons = false; private Media video; private String dataSource; private String pendingDataURI; private boolean autoplay; private boolean loop; //private Runnable onCompletion; /** * Empty constructor */ public MediaPlayer() { playIcon = FontImage.createMaterial(FontImage.MATERIAL_PLAY_ARROW, "Button", 3); pauseIcon = FontImage.createMaterial(FontImage.MATERIAL_PAUSE, "Button", 3); fwdIcon = FontImage.createMaterial(FontImage.MATERIAL_FAST_FORWARD, "Button", 3); backIcon = FontImage.createMaterial(FontImage.MATERIAL_FAST_REWIND, "Button", 3); maxIcon = FontImage.createMaterial(FontImage.MATERIAL_FULLSCREEN, "Button", 3); } /** * On platforms that include native video player controls (Android and iOS), this allows you * to hide those controls. * @param hideNativeControls Set {@literal true} to hide the native video controls for this player. * @see Display#isNativeVideoPlayerControlsIncluded() * @see #setHideNativeVideoControls(boolean) * @see #usesNativeVideoControls() */ public void setHideNativeVideoControls(boolean hideNativeControls) { this.hideNativeVideoControls = hideNativeControls; if (video != null) { video.setVariable(Media.VARIABLE_NATIVE_CONTRLOLS_EMBEDDED, !hideNativeControls && showControls); } } /** * On platforms that include native video player controls (Android and iOS), this indicates whether * these controls should be hidden for this media player. * @return {@literal true} if native video player controls should be hidden. * @see Display#isNativeVideoPlayerControlsIncluded() * @see #setHideNativeVideoControls(boolean) * @see #usesNativeVideoControls() */ public boolean isHideNativeVideoControls() { return hideNativeVideoControls; } /** * Checks to see if this player uses native video controls. For this to be {@literal true}, * the platform must support native video controls (iOS and Android) (See {@link Display#isNativeVideoPlayerControlsIncluded() } * to find out if current platform supports this; AND {@link #isHideNativeVideoControls() } * must be false. * *

Note: on IOS, the controls won't display until the video's {@link Media#prepare() } * is called. This will happen automatically if {@link #isAutoplay() } is true, or if {@link Media#play() } * is called.

* @return True if this player uses native video controls. * @see #isHideNativeVideoControls() * @see #setHideNativeVideoControls(boolean) * @see Display#isNativeVideoPlayerControlsIncluded() */ public boolean usesNativeVideoControls() { return Display.getInstance().isNativeVideoPlayerControlsIncluded() && !hideNativeVideoControls; } /** * Shows the controls for this media player. If the player is set to use * native controls, then this will show the native controls. Otherwise it * shows the lightweight controls. *

Note: on IOS, the controls won't display until the video's {@link Media#prepare() } * is called. This will happen automatically if {@link #isAutoplay() } is true, or if {@link Media#play() } * is called.

*/ public void showControls() { if (!showControls) { showControls = true; if (isInitialized()) { buttonsBar.setVisible(true); buttonsBar.setHidden(false); animateLayoutFade(300, 0); } } if (video != null && usesNativeVideoControls()) { video.setVariable(Media.VARIABLE_NATIVE_CONTRLOLS_EMBEDDED, true); } } /** * Hides the controls for this media player. If the player is set to use native * controls, then this will hide the native controls. Otherwise it hides the * lightweight controls. */ public void hideControls() { if (showControls) { showControls = false; if (isInitialized()) { buttonsBar.setVisible(false); buttonsBar.setHidden(true); animateLayoutFade(300, 0); } } if (video != null && usesNativeVideoControls()) { video.setVariable(Media.VARIABLE_NATIVE_CONTRLOLS_EMBEDDED, false); } } /** * Empty constructor */ public MediaPlayer(Media video) { this(); this.video = video; updateLoopOnCompletionHandler(); //initUI(); } /** * Returns the Media Object of this MediaPlayer * @return */ public Media getMedia(){ return video; } /** * {@inheritDoc} */ protected void initComponent() { if(userSetIcons){ Image play = UIManager.getInstance().getThemeImageConstant("mediaPlayImage"); if(play != null){ playIcon = play; } Image pause = UIManager.getInstance().getThemeImageConstant("mediaPauseImage"); if(pause != null){ pauseIcon = pause; } Image back = UIManager.getInstance().getThemeImageConstant("mediaBackImage"); if(back != null){ backIcon = back; } Image fwd = UIManager.getInstance().getThemeImageConstant("mediaFwdImage"); if(fwd != null){ fwdIcon = fwd; } Image max = UIManager.getInstance().getThemeImageConstant("mediaMaxImage"); if(max != null){ maxIcon = max; } } if(pendingDataURI != null) { setDataSource(pendingDataURI); pendingDataURI = null; } initUI(); } private void checkProgressSlider() { if(progressUpdater == null) { progressUpdater = UITimer.timer(50, true, getComponentForm(), new Runnable() { public void run() { float dur = video.getDuration(); if(dur > 0) { float pos = video.getTime(); int offset = (int)(pos / dur * 100.0f); if(offset > -1 && offset < 101) { if (progress != null) { progress.setProgress(offset); } } } } }); } } private void stopProgressSlider() { if(progressUpdater != null) { progressUpdater.cancel(); progressUpdater = null; } } /** * {@inheritDoc} */ @Override protected void deinitialize() { super.deinitialize(); if(video != null && video.isPlaying()){ video.pause(); stopProgressSlider(); } } /** * {@inheritDoc} */ protected Dimension calcPreferredSize() { if(video == null && dataSource == null) { return new Dimension(240, 320); } return super.calcPreferredSize(); } /** * Sets the back Button Icon * @param backIcon */ public void setBackIcon(Image backIcon) { this.backIcon = backIcon; userSetIcons = true; } /** * Sets the forward Button Icon * @param fwdIcon */ public void setFwdIcon(Image fwdIcon) { this.fwdIcon = fwdIcon; userSetIcons = true; } /** * Sets the maximize Button Icon * @param maxIcon */ public void setMaxIcon(Image maxIcon ) { this.maxIcon = maxIcon ; userSetIcons = true; } /** * Sets the pause Button Icon * @param pauseIcon */ public void setPauseIcon(Image pauseIcon) { this.pauseIcon = pauseIcon; userSetIcons = true; } /** * Sets the play Button Icon * @param playIcon */ public void setPlayIcon(Image playIcon) { this.playIcon = playIcon; userSetIcons = true; } /** * Sets the data source of this video player * @param uri the uri of the media can start with file://, http:// (can also * use rtsp:// although may not be supported on all target platforms) * @throws IOException if creation of media from the given URI has failed */ public void setDataSource(String uri, Runnable onCompletion) throws IOException{ dataSource = uri; video = MediaManager.createMedia(uri, true, onCompletion); updateLoopOnCompletionHandler(); if (isInitialized()) { initUI(); } } /** * Convenience JavaBean method, see other version of this method * @param uri the URL for the media */ public void setDataSource(final String uri) { if(!isInitialized()) { pendingDataURI = uri; return; } if(dataSource == null || !dataSource.equals(uri)) { Display.getInstance().startThread(new Runnable() { public void run() { try { setDataSource(uri, null); } catch(Throwable t) { Log.e(t); } } }, "Media Thread").start(); } } /** * Convenience JavaBean method, see other version of this method * * @return the data source uri */ public String getDataSource() { if(!isInitialized() && dataSource == null) { return pendingDataURI; } return dataSource; } /** * Sets the data source of this video player * @param is the stream containing the media data * @param mimeType the type of the data in the stream * @throws java.io.IOException if the creation of the Media has failed */ public void setDataSource(InputStream is, String mimeType, Runnable onCompletion) throws IOException{ video = MediaManager.createMedia(is, mimeType, onCompletion); updateLoopOnCompletionHandler(); if (isInitialized()) { initUI(); } } private void initUI() { removeAll(); if(onTopMode) { setLayout(new LayeredLayout()); } else { setLayout(new BorderLayout()); } if(video != null && video.getVideoComponent() != null){ Component videoComponent = video.getVideoComponent(); if (videoComponent != null) { videoComponent.setUIID("Container"); if(onTopMode) { addComponent(videoComponent); } else { addComponent(BorderLayout.CENTER, videoComponent); } } } if(seekBar) { buttonsBar = new Container(new BorderLayout()); progress = new Slider(); progress.setEditable(true); buttonsBar.addComponent(BorderLayout.CENTER, FlowLayout.encloseCenterMiddle(progress)); progress.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { float dur = video.getDuration(); if(dur > 0) { if (progress != null) { float pos = progress.getProgress(evt); int t = (int)(pos / 100.0f * dur); video.setTime(t); } } } }); } else { buttonsBar = new Container(new FlowLayout(Container.CENTER)); } if(onTopMode) { addComponent(BorderLayout.south(buttonsBar)); } else { addComponent(BorderLayout.SOUTH, buttonsBar); } if (usesNativeVideoControls() || !showControls) { buttonsBar.setVisible(false); buttonsBar.setHidden(true); } if(!seekBar) { Button back = new Button(); back.setUIID("MediaPlayerBack"); if(backIcon != null){ back.setIcon(backIcon); }else{ back.setText("Back"); } buttonsBar.addComponent(back); back.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(video == null){ return; } int t = video.getTime(); video.setTime(t - 2); } }); } final Button play = new Button() { private ActionListener stateChangeListener = new ActionListener() { @Override public void actionPerformed(AsyncMedia.MediaStateChangeEvent evt) { updateIconAndText(); } }; private void updateIconAndText() { if (video != null && video.isPlaying()) { if (getPauseIcon() != null) { this.setIcon(getPauseIcon()); } else { this.setText("pause"); } } else { if(playIcon != null){ this.setIcon(playIcon); }else{ this.setText("play"); } } } @Override protected void initComponent() { super.initComponent(); updateIconAndText(); if (video != null) { MediaManager.getAsyncMedia(video).addMediaStateChangeListener(stateChangeListener); } } @Override protected void deinitialize() { if (video != null) { MediaManager.getAsyncMedia(video).removeMediaStateChangeListener(stateChangeListener); } super.deinitialize(); } }; play.setUIID("MediaPlayerPlay"); if(playIcon != null){ play.setIcon(playIcon); }else{ play.setText("play"); } if(autoplay) { if(video != null && !video.isPlaying()){ if (getPauseIcon() != null) { play.setIcon(getPauseIcon()); } else { play.setText("pause"); } Timer t = new Timer(); t.schedule(new TimerTask() { public void run() { if (isInitialized()) { Display.getInstance().callSerially(new Runnable() { public void run() { if (video != null && !video.isPlaying() && isInitialized()) { video.play(); checkProgressSlider(); } } }); } } }, 300l); //video.play(); } } play.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(video == null){ return; } if(!video.isPlaying()){ video.play(); checkProgressSlider(); play.setUIID("MediaPlayerPause"); if (getPauseIcon() != null) { play.setIcon(getPauseIcon()); } else { play.setText("pause"); } play.repaint(); }else{ video.pause(); stopProgressSlider(); play.setUIID("MediaPlayerPlay"); if (getPlayIcon() != null) { play.setIcon(getPlayIcon()); } else { play.setText("play"); } play.repaint(); } } }); Display.getInstance().callSerially(new Runnable() { public void run() { if (video != null && video.isPlaying()) { play.setUIID("MediaPlayerPause"); if (getPauseIcon() != null) { play.setIcon(getPauseIcon()); } else { play.setText("pause"); } } else if (video != null && !video.isPlaying()) { play.setUIID("MediaPlayerPlay"); if (getPlayIcon() != null) { play.setIcon(getPlayIcon()); } else { play.setText("play"); } } } }); if(seekBar) { buttonsBar.addComponent(BorderLayout.WEST, play); } else { buttonsBar.addComponent(play); } //if(video == null || !video.isNativePlayerMode()){ if(!seekBar) { Button fwd = new Button(); fwd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(video == null){ return; } int t = video.getTime(); video.setTime(t + 1); } }); fwd.setUIID("MediaPlayerFwd"); if(fwdIcon != null){ fwd.setIcon(fwdIcon); }else{ fwd.setText("fwd"); } buttonsBar.addComponent(fwd); } if(maximize && video != null && video.isVideo()) { Button max = new Button(); max.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(video == null){ return; } video.setNativePlayerMode(true); } }); max.setUIID("MediaPlayerMax"); if(maxIcon != null){ max.setIcon(maxIcon); }else{ max.setText("max"); } if(seekBar) { buttonsBar.addComponent(BorderLayout.EAST, max); } else { buttonsBar.addComponent(max); } } //} if(isInitialized()) { revalidate(); } } public void run() { } /** * {@inheritDoc} */ public String[] getPropertyNames() { return new String[] {"backIcon", "forwardIcon", "pauseIcon", "playIcon", "dataSource"}; } /** * {@inheritDoc} */ public Class[] getPropertyTypes() { return new Class[] {Image.class, Image.class, Image.class, Image.class, String.class}; } /** * {@inheritDoc} */ public Object getPropertyValue(String name) { if(name.equals("backIcon")) { return getBackIcon(); } if(name.equals("forwardIcon")) { return getFwdIcon(); } if(name.equals("playIcon")) { return getPlayIcon(); } if(name.equals("pauseIcon")) { return getPauseIcon(); } if(name.equals("dataSource")) { return getDataSource(); } return super.getPropertyValue(name); } /** * {@inheritDoc} */ public String setPropertyValue(String name, Object value) { if(name.equals("backIcon")) { this.backIcon = (Image)value; return null; } if(name.equals("forwardIcon")) { this.fwdIcon = (Image)value; return null; } if(name.equals("playIcon")) { this.playIcon = (Image)value; return null; } if(name.equals("pauseIcon")) { this.pauseIcon = (Image)value; return null; } if(name.equals("dataSource")) { setDataSource((String)value); return null; } return super.setPropertyValue(name, value); } /** * @return the playIcon */ public Image getPlayIcon() { return playIcon; } /** * @return the pauseIcon */ public Image getPauseIcon() { return pauseIcon; } /** * @return the backIcon */ public Image getBackIcon() { return backIcon; } /** * @return the fwdIcon */ public Image getFwdIcon() { return fwdIcon; } /** * Sets playback to start automatically * @return the autoplay */ public boolean isAutoplay() { return autoplay; } /** * Sets playback to start automatically * @param autoplay the autoplay to set */ public void setAutoplay(boolean autoplay) { this.autoplay = autoplay; } /** * Sets playback to loop * @return the loop */ public boolean isLoop() { return loop; } private void updateLoopOnCompletionHandler() { if (isLoop() && loopOnCompletion == null) { loopOnCompletion = new Runnable() { @Override public void run() { if (video != null) { video.setTime(0); video.play(); checkProgressSlider(); } } }; } if (isLoop()) { Display.getInstance().addCompletionHandler(video, loopOnCompletion); } else { if (loopOnCompletion != null) { Display.getInstance().removeCompletionHandler(video, loopOnCompletion); } } } /** * Sets playback to loop * @param loop the loop to set */ public void setLoop(boolean loop) { if (loop != this.loop) { this.loop = loop; updateLoopOnCompletionHandler(); } } /* class CompletionWrapper implements Runnable { public void run() { if(onCompletion != null) { onCompletion.run(); } if(isLoop()) { try { setDataSource(dataSource, this); } catch(IOException err) { Log.e(err); } } } } */ /** * Shows the buttons on top of the video * @return the onTopMode */ public boolean isOnTopMode() { return onTopMode; } /** * Shows the buttons on top of the video * @param onTopMode the onTopMode to set */ public void setOnTopMode(boolean onTopMode) { this.onTopMode = onTopMode; } /** * Shows video position bar as a slider * @return the seekBar */ public boolean isSeekBar() { return seekBar; } /** * Shows video position bar as a slider * @param seekBar the seekBar to set */ public void setSeekBar(boolean seekBar) { this.seekBar = seekBar; } /** * UIID for the seekBar slider * @return the seekBarUIID */ public String getSeekBarUIID() { return seekBarUIID; } /** * UIID for the seekBar slider * @param seekBarUIID the seekBarUIID to set */ public void setSeekBarUIID(String seekBarUIID) { this.seekBarUIID = seekBarUIID; } /** * Includes a maximize icon in the bar to show the native player * @return the maximize */ public boolean isMaximize() { return maximize; } /** * Includes a maximize icon in the bar to show the native player * @param maximize the maximize to set */ public void setMaximize(boolean maximize) { this.maximize = maximize; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy