/** * Sets whether the video should be shown in fullscreen or not. * * @param value If True, the video will be shown in fullscreen. If False and {@link * VideoPlayer#FullScreen()} returns True, fullscreen mode will be exited. If False and {@link * VideoPlayer#FullScreen()} returns False, nothing occurs. */ @SimpleProperty(userVisible = true) public void FullScreen(boolean value) { if (value && (SdkLevel.getLevel() <= SdkLevel.LEVEL_DONUT)) { container .$form() .dispatchErrorOccurredEvent( this, "FullScreen(true)", ErrorMessages.ERROR_VIDEOPLAYER_FULLSCREEN_UNSUPPORTED); return; } if (value != inFullScreen) { if (value) { Bundle data = new Bundle(); data.putInt(FullScreenVideoUtil.VIDEOPLAYER_POSITION, videoView.getCurrentPosition()); data.putBoolean(FullScreenVideoUtil.VIDEOPLAYER_PLAYING, videoView.isPlaying()); videoView.pause(); data.putBoolean(FullScreenVideoUtil.VIDEOPLAYER_FULLSCREEN, true); data.putString(FullScreenVideoUtil.VIDEOPLAYER_SOURCE, sourcePath); Bundle result = container .$form() .fullScreenVideoAction( FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_FULLSCREEN, this, data); if (result.getBoolean(FullScreenVideoUtil.ACTION_SUCESS)) { inFullScreen = true; } else { inFullScreen = false; container .$form() .dispatchErrorOccurredEvent( this, "FullScreen", ErrorMessages.ERROR_VIDEOPLAYER_FULLSCREEN_UNAVAILBLE, ""); } } else { Bundle values = new Bundle(); values.putBoolean(FullScreenVideoUtil.VIDEOPLAYER_FULLSCREEN, false); Bundle result = container .$form() .fullScreenVideoAction( FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_FULLSCREEN, this, values); if (result.getBoolean(FullScreenVideoUtil.ACTION_SUCESS)) { fullScreenKilled((Bundle) result); } else { inFullScreen = true; container .$form() .dispatchErrorOccurredEvent( this, "FullScreen", ErrorMessages.ERROR_VIDEOPLAYER_FULLSCREEN_CANT_EXIT, ""); } } } }
/** * Notify this VideoPlayer that its video is no longer being shown in fullscreen. * * @param data See {@link com.google.appinventor.components.runtime.util.FullScreenVideoUtil} for * an example of what data should contain. */ public void fullScreenKilled(Bundle data) { inFullScreen = false; String newSource = data.getString(FullScreenVideoUtil.VIDEOPLAYER_SOURCE); if (!newSource.equals(sourcePath)) { Source(newSource); } videoView.setVisibility(View.VISIBLE); videoView.requestLayout(); SeekTo(data.getInt(FullScreenVideoUtil.VIDEOPLAYER_POSITION)); if (data.getBoolean(FullScreenVideoUtil.VIDEOPLAYER_PLAYING)) { Start(); } }
@Override public boolean onError(MediaPlayer m, int what, int extra) { // The ResizableVideoView onMeasure method attempts to use the MediaPlayer // to measure // the VideoPlayer; but in the event of an error, the MediaPlayer // may report dimensions of zero video width and height. // Since VideoPlayer currently (7/10/2012) sets its size always // to some non-zero number, the MediaPlayer is invalidated here // to prevent onMeasure from setting width and height as zero. videoView.invalidateMediaPlayer(true); delayedStart = false; mediaReady = false; Log.e( "VideoPlayer", "onError: what is " + what + " 0x" + Integer.toHexString(what) + ", extra is " + extra + " 0x" + Integer.toHexString(extra)); container .$form() .dispatchErrorOccurredEvent( this, "Source", ErrorMessages.ERROR_UNABLE_TO_LOAD_MEDIA, sourcePath); return true; }
/** * Specifies the component's vertical height, measured in pixels. * * @param height in pixels */ @Override @SimpleProperty(userVisible = true) public void Height(int height) { super.Height(height); // Forces a layout of the ResizableVideoView videoView.changeVideoSize(videoView.forcedWidth, height); }
/** * Specifies the component's horizontal width, measured in pixels. * * @param width in pixels */ @Override @SimpleProperty(userVisible = true) public void Width(int width) { super.Width(width); // Forces a layout of the ResizableVideoView videoView.changeVideoSize(width, videoView.forcedHeight); }
/** * Sets the video source. * * <p>See {@link MediaUtil#determineMediaSource} for information about what a path can be. * * @param path the path to the video source */ @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_ASSET, defaultValue = "") @SimpleProperty( description = "The \"path\" to the video. Usually, this will be the " + "name of the video file, which should be added in the Designer.", category = PropertyCategory.BEHAVIOR) public void Source(String path) { if (inFullScreen) { container .$form() .fullScreenVideoAction(FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_SOURCE, this, path); } else { sourcePath = (path == null) ? "" : path; // The source may change for the MediaPlayer, and // getVideoWidth or getVideoHeight may be called // creating an error in ResizableVideoView. videoView.invalidateMediaPlayer(true); // Clear the previous video. if (videoView.isPlaying()) { videoView.stopPlayback(); } videoView.setVideoURI(null); videoView.clearAnimation(); if (sourcePath.length() > 0) { Log.i("VideoPlayer", "Source path is " + sourcePath); try { mediaReady = false; MediaUtil.loadVideoView(videoView, container.$form(), sourcePath); } catch (IOException e) { container .$form() .dispatchErrorOccurredEvent( this, "Source", ErrorMessages.ERROR_UNABLE_TO_LOAD_MEDIA, sourcePath); return; } Log.i("VideoPlayer", "loading video succeeded"); } } }
private void prepareToDie() { if (videoView.isPlaying()) { videoView.stopPlayback(); } videoView.setVideoURI(null); videoView.clearAnimation(); delayedStart = false; mediaReady = false; if (inFullScreen) { Bundle data = new Bundle(); data.putBoolean(FullScreenVideoUtil.VIDEOPLAYER_FULLSCREEN, false); container .$form() .fullScreenVideoAction( FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_FULLSCREEN, this, data); } }
@Override public void onPrepared(MediaPlayer newMediaPlayer) { mediaReady = true; delayedStart = false; mPlayer = newMediaPlayer; videoView.setMediaPlayer(mPlayer, true); if (delayedStart) { Start(); } }
/** * Creates a new VideoPlayer component. * * @param container */ public VideoPlayer(ComponentContainer container) { super(container); container.$form().registerForOnDestroy(this); videoView = new ResizableVideoView(container.$context()); videoView.setMediaController(new MediaController(container.$context())); videoView.setOnCompletionListener(this); videoView.setOnErrorListener(this); videoView.setOnPreparedListener(this); // add the component to the designated container container.$add(this); // set a default size container.setChildWidth(this, ComponentConstants.VIDEOPLAYER_PREFERRED_WIDTH); container.setChildHeight(this, ComponentConstants.VIDEOPLAYER_PREFERRED_HEIGHT); // Make volume buttons control media, not ringer. container.$form().setVolumeControlStream(AudioManager.STREAM_MUSIC); sourcePath = ""; }
/** * Plays the media specified by the source. These won't normally be used in the most elementary * applications, because videoView brings up its own player controls when the video is touched. */ @SimpleFunction(description = "Starts playback of the video.") public void Start() { Log.i("VideoPlayer", "Calling Start"); if (inFullScreen) { container .$form() .fullScreenVideoAction(FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_PLAY, this, null); } else { if (mediaReady) { videoView.start(); } else { delayedStart = true; } } }
@SimpleFunction( description = "Pauses playback of the video. Playback can be resumed " + "at the same location by calling the <code>Start</code> method.") public void Pause() { Log.i("VideoPlayer", "Calling Pause"); if (inFullScreen) { container .$form() .fullScreenVideoAction(FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_PAUSE, this, null); delayedStart = false; } else { delayedStart = false; videoView.pause(); } }
@SimpleFunction(description = "Returns duration of the video in milliseconds.") public int GetDuration() { Log.i("VideoPlayer", "Calling GetDuration"); if (inFullScreen) { Bundle result = container .$form() .fullScreenVideoAction( FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_DURATION, this, null); if (result.getBoolean(FullScreenVideoUtil.ACTION_SUCESS)) { return result.getInt(FullScreenVideoUtil.ACTION_DATA); } else { return 0; } } else { return videoView.getDuration(); } }
@SimpleFunction( description = "Seeks to the requested time (specified in milliseconds) in the video. " + "Note that if the video is paused, the frame shown will not be updated by the seek. ") public void SeekTo(int ms) { Log.i("VideoPlayer", "Calling SeekTo"); if (ms < 0) { ms = 0; } if (inFullScreen) { container .$form() .fullScreenVideoAction(FullScreenVideoUtil.FULLSCREEN_VIDEO_ACTION_SEEK, this, ms); } else { // There is no harm if the milliseconds is longer than the duration. videoView.seekTo(ms); } }