/*
* Copyright 2012 Google Inc. All Rights Reserved.
*
* 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 com.examples.youtubeapidemo;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.ErrorReason;
import com.google.android.youtube.player.YouTubePlayer.PlaybackEventListener;
import com.google.android.youtube.player.YouTubePlayer.PlayerStateChangeListener;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayer.PlaylistEventListener;
import com.google.android.youtube.player.YouTubePlayerView;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
/**
* A simple YouTube Android API demo application demonstrating the use of {@link YouTubePlayer}
* programmatic controls.
*/
public class PlayerControlsDemoActivity extends YouTubeFailureRecoveryActivity implements
View.OnClickListener,
TextView.OnEditorActionListener,
CompoundButton.OnCheckedChangeListener,
AdapterView.OnItemSelectedListener {
private static final ListEntry[] ENTRIES = {
new ListEntry("Androidify App", "irH3OSOskcE", false),
new ListEntry("Chrome Speed Tests", "nCgQDjiotG0", false),
new ListEntry("Playlist: Google I/O 2012", "PL56D792A831D0C362", true)};
private static final String KEY_CURRENTLY_SELECTED_ID = "currentlySelectedId";
private YouTubePlayerView youTubePlayerView;
private YouTubePlayer player;
private TextView stateText;
private ArrayAdapter<ListEntry> videoAdapter;
private Spinner videoChooser;
private Button playButton;
private Button pauseButton;
private EditText skipTo;
private TextView eventLog;
private StringBuilder logString;
private RadioGroup styleRadioGroup;
private MyPlaylistEventListener playlistEventListener;
private MyPlayerStateChangeListener playerStateChangeListener;
private MyPlaybackEventListener playbackEventListener;
private int currentlySelectedPosition;
private String currentlySelectedId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_controls_demo);
youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtube_view);
stateText = (TextView) findViewById(R.id.state_text);
videoChooser = (Spinner) findViewById(R.id.video_chooser);
playButton = (Button) findViewById(R.id.play_button);
pauseButton = (Button) findViewById(R.id.pause_button);
skipTo = (EditText) findViewById(R.id.skip_to_text);
eventLog = (TextView) findViewById(R.id.event_log);
styleRadioGroup = (RadioGroup) findViewById(R.id.style_radio_group);
((RadioButton) findViewById(R.id.style_default)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.style_minimal)).setOnCheckedChangeListener(this);
((RadioButton) findViewById(R.id.style_chromeless)).setOnCheckedChangeListener(this);
logString = new StringBuilder();
videoAdapter = new ArrayAdapter<ListEntry>(this, android.R.layout.simple_spinner_item, ENTRIES);
videoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
videoChooser.setOnItemSelectedListener(this);
videoChooser.setAdapter(videoAdapter);
playButton.setOnClickListener(this);
pauseButton.setOnClickListener(this);
skipTo.setOnEditorActionListener(this);
youTubePlayerView.initialize(DeveloperKey.DEVELOPER_KEY, this);
playlistEventListener = new MyPlaylistEventListener();
playerStateChangeListener = new MyPlayerStateChangeListener();
playbackEventListener = new MyPlaybackEventListener();
setControlsEnabled(false);
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
boolean wasRestored) {
this.player = player;
player.setPlaylistEventListener(playlistEventListener);
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
if (!wasRestored) {
playVideoAtSelection();
}
setControlsEnabled(true);
}
@Override
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return youTubePlayerView;
}
private void playVideoAtSelection() {
ListEntry selectedEntry = videoAdapter.getItem(currentlySelectedPosition);
if (selectedEntry.id != currentlySelectedId && player != null) {
currentlySelectedId = selectedEntry.id;
if (selectedEntry.isPlaylist) {
player.cuePlaylist(selectedEntry.id);
} else {
player.cueVideo(selectedEntry.id);
}
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
currentlySelectedPosition = pos;
playVideoAtSelection();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
@Override
public void onClick(View v) {
if (v == playButton) {
player.play();
} else if (v == pauseButton) {
player.pause();
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (v == skipTo) {
int skipToSecs = parseInt(skipTo.getText().toString(), 0);
player.seekToMillis(skipToSecs * 1000);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(skipTo.getWindowToken(), 0);
return true;
}
return false;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked && player != null) {
switch (buttonView.getId()) {
case R.id.style_default:
player.setPlayerStyle(PlayerStyle.DEFAULT);
break;
case R.id.style_minimal:
player.setPlayerStyle(PlayerStyle.MINIMAL);
break;
case R.id.style_chromeless:
player.setPlayerStyle(PlayerStyle.CHROMELESS);
break;
}
}
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putString(KEY_CURRENTLY_SELECTED_ID, currentlySelectedId);
}
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
currentlySelectedId = state.getString(KEY_CURRENTLY_SELECTED_ID);
}
private void updateText() {
stateText.setText(String.format("Current state: %s %s %s",
playerStateChangeListener.playerState, playbackEventListener.playbackState,
playbackEventListener.bufferingState));
}
private void log(String message) {
logString.append(message + "\n");
eventLog.setText(logString);
}
private void setControlsEnabled(boolean enabled) {
playButton.setEnabled(enabled);
pauseButton.setEnabled(enabled);
skipTo.setEnabled(enabled);
videoChooser.setEnabled(enabled);
for (int i = 0; i < styleRadioGroup.getChildCount(); i++) {
styleRadioGroup.getChildAt(i).setEnabled(enabled);
}
}
private static final int parseInt(String intString, int defaultValue) {
try {
return intString != null ? Integer.valueOf(intString) : defaultValue;
} catch (NumberFormatException e) {
return defaultValue;
}
}
private String formatTime(int millis) {
int seconds = millis / 1000;
int minutes = seconds / 60;
int hours = minutes / 60;
return (hours == 0 ? "" : hours + ":")
+ String.format("%02d:%02d", minutes % 60, seconds % 60);
}
private String getTimesText() {
int currentTimeMillis = player.getCurrentTimeMillis();
int durationMillis = player.getDurationMillis();
return String.format("(%s/%s)", formatTime(currentTimeMillis), formatTime(durationMillis));
}
private final class MyPlaylistEventListener implements PlaylistEventListener {
@Override
public void onNext() {
log("NEXT VIDEO");
}
@Override
public void onPrevious() {
log("PREVIOUS VIDEO");
}
@Override
public void onPlaylistEnded() {
log("PLAYLIST ENDED");
}
}
private final class MyPlaybackEventListener implements PlaybackEventListener {
String playbackState = "NOT_PLAYING";
String bufferingState = "";
@Override
public void onPlaying() {
playbackState = "PLAYING";
updateText();
log("\tPLAYING " + getTimesText());
}
@Override
public void onBuffering(boolean isBuffering) {
bufferingState = isBuffering ? "(BUFFERING)" : "";
updateText();
log("\t\t" + (isBuffering ? "BUFFERING " : "NOT BUFFERING ") + getTimesText());
}
@Override
public void onStopped() {
playbackState = "STOPPED";
updateText();
log("\tSTOPPED");
}
@Override
public void onPaused() {
playbackState = "PAUSED";
updateText();
log("\tPAUSED " + getTimesText());
}
@Override
public void onSeekTo(int endPositionMillis) {
log(String.format("\tSEEKTO: (%s/%s)",
formatTime(endPositionMillis),
formatTime(player.getDurationMillis())));
}
}
private final class MyPlayerStateChangeListener implements PlayerStateChangeListener {
String playerState = "UNINITIALIZED";
@Override
public void onLoading() {
playerState = "LOADING";
updateText();
log(playerState);
}
@Override
public void onLoaded(String videoId) {
playerState = String.format("LOADED %s", videoId);
updateText();
log(playerState);
}
@Override
public void onAdStarted() {
playerState = "AD_STARTED";
updateText();
log(playerState);
}
@Override
public void onVideoStarted() {
playerState = "VIDEO_STARTED";
updateText();
log(playerState);
}
@Override
public void onVideoEnded() {
playerState = "VIDEO_ENDED";
updateText();
log(playerState);
}
@Override
public void onError(ErrorReason reason) {
playerState = "ERROR (" + reason + ")";
if (reason == ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
// When this error occurs the player is released and can no longer be used.
player = null;
setControlsEnabled(false);
}
updateText();
log(playerState);
}
}
private static final class ListEntry {
public final String title;
public final String id;
public final boolean isPlaylist;
public ListEntry(String title, String videoId, boolean isPlaylist) {
this.title = title;
this.id = videoId;
this.isPlaylist = isPlaylist;
}
@Override
public String toString() {
return title;
}
}
}