[Android] [PATCH 3/5] Remote playback: add the RemotePlaybackActivity to control remote playback devices such as a Chromecast
Adrien Maglo
magsoft at gmail.com
Tue Jul 8 16:33:47 CEST 2014
---
vlc-android/AndroidManifest.xml | 4 +
vlc-android/res/values/strings.xml | 4 +
.../vlc/gui/video/RemotePlaybackActivity.java | 241 +++++++++++++++++++++
3 files changed, 249 insertions(+)
create mode 100644 vlc-android/src/org/videolan/vlc/gui/video/RemotePlaybackActivity.java
diff --git a/vlc-android/AndroidManifest.xml b/vlc-android/AndroidManifest.xml
index dba015c..4311b54 100644
--- a/vlc-android/AndroidManifest.xml
+++ b/vlc-android/AndroidManifest.xml
@@ -368,6 +368,10 @@
<data android:pathPattern=".*\\.XM" />
</intent-filter>
</activity>
+ <activity
+ android:name=".gui.video.RemotePlaybackActivity"
+ android:configChanges="orientation|screenSize"
+ android:theme="@style/Theme.VLC.Fullscreen" />
<service android:name="org.videolan.vlc.audio.AudioService" />
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index d9a2a11..a31ca4b 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -191,6 +191,10 @@
<string name="about_copyright" translatable="false">Copyleft © 1996–2014 by VideoLAN.\n</string>
<string name="authors" translatable="false">Edward Wang, Sébastien Toque, Adrien Maglo, Jean-Baptiste Kempf, Ludovic Fauvet, Rafaël Carré, Alexandre Perraud, Michael Merg, Martin Storsjö, Rémi Duraffort, Dominique Martinet, Jean-Philippe André, Felix Abecassis, Christoph Miebach, Hugo Beauzée-Luyssen, Felix Paul Kühne, John Mooring, Pavol Rusnak, Rohit Yadav, Tanguy Pruvot, Thomas Clavier, Asad Mehmood, Garret Kelly, Philipp Dreimann, Walter Heck.</string>
+ <!-- RemotePlayback -->
+ <string name="no_cast_device">No cast device found.</string>
+ <string name="check_remote">Check your wifi and cast device.</string>
+
<!-- Preferences -->
<string name="preferences">Preferences</string>
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/RemotePlaybackActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/RemotePlaybackActivity.java
new file mode 100644
index 0000000..4f5b94e
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/video/RemotePlaybackActivity.java
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ * RemotePlaybackActivity.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc.gui.video;
+
+import java.util.List;
+import org.videolan.vlc.R;
+import org.videolan.vlc.RemotePlaybackHTTPServer;
+
+import android.app.Activity;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v7.app.MediaRouteChooserDialog;
+import android.support.v7.media.MediaControlIntent;
+import android.support.v7.media.MediaItemStatus;
+import android.support.v7.media.MediaRouteSelector;
+import android.support.v7.media.MediaRouter;
+import android.support.v7.media.MediaRouter.RouteInfo;
+import android.support.v7.media.MediaSessionStatus;
+import android.support.v7.media.RemotePlaybackClient;
+import android.support.v7.media.RemotePlaybackClient.ItemActionCallback;
+import android.support.v7.media.RemotePlaybackClient.SessionActionCallback;
+import android.support.v7.media.RemotePlaybackClient.StatusCallback;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+
+public class RemotePlaybackActivity extends Activity {
+
+ public final static String TAG = "VLC/RemotePlaybackActivity";
+
+ private MediaRouteSelector mSelector;
+ private MediaRouter mMediaRouter;
+ private RemotePlaybackClient mRemotePlaybackClient;
+ private RouteInfo mRoute;
+ private RemotePlaybackHTTPServer mServer;
+
+ private ImageButton mPlayPause;
+ private ImageButton mRouteChooser;
+ private TextView mDeviceName;
+ private TextView mDeviceType;
+
+ private enum State {STOPED, PLAYING, PAUSED}
+ private State mState = State.STOPED;
+ private String mItemLocation;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.remote_playback);
+
+ mPlayPause = (ImageButton) findViewById(R.id.play_pause);
+ mRouteChooser = (ImageButton) findViewById(R.id.route_chooser);
+ mDeviceName = (TextView) findViewById(R.id.device_name);
+ mDeviceType = (TextView) findViewById(R.id.device_type);
+
+ mItemLocation = getIntent().getExtras().getString("itemLocation");
+
+ mSelector = new MediaRouteSelector.Builder()
+ .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
+ .build();
+
+ mMediaRouter = MediaRouter.getInstance(this);
+ }
+
+
+ @Override
+ public void onStart() {
+ List<RouteInfo> routes = mMediaRouter.getRoutes();
+ for (RouteInfo route : routes)
+ if (route.getPlaybackType() == RouteInfo.PLAYBACK_TYPE_REMOTE) {
+ if (!route.isSelected())
+ mMediaRouter.selectRoute(route);
+ else
+ setCurrentRoute(route);
+ }
+
+ mMediaRouter.addCallback(mSelector, mMediaRouterCallback,
+ MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+
+ super.onStart();
+ }
+
+
+ @Override
+ public void onPause() {
+ stop();
+ super.onPause();
+ }
+
+ @Override
+ public void onStop() {
+ mMediaRouter.removeCallback(mMediaRouterCallback);
+ super.onStop();
+ }
+
+
+ private final MediaRouter.Callback mMediaRouterCallback =
+ new MediaRouter.Callback() {
+
+ @Override
+ public void onRouteAdded(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "Route added.");
+ if (mRoute == null)
+ router.selectRoute(route);
+ }
+
+ @Override
+ public void onRouteSelected(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "Route selected.");
+ setCurrentRoute(route);
+ }
+
+ @Override
+ public void onRouteUnselected(MediaRouter router, RouteInfo route) {
+ if (route == mRoute) {
+ Log.d(TAG, "Route unselected.");
+ stop();
+ setCurrentRoute(null);
+ }
+ }
+ };
+
+
+ private void setCurrentRoute(RouteInfo route) {
+ mRoute = route;
+ mDeviceName.setText(route == null ?
+ getString(R.string.no_cast_device) : mRoute.getName());
+ mDeviceType.setText(route == null ?
+ getString(R.string.check_remote) : mRoute.getDescription());
+ }
+
+
+ private void play(RouteInfo route) {
+ if (route == null)
+ return;
+
+ if (mRemotePlaybackClient != null)
+ throw new IllegalStateException("Remote playback client already instantiated.");
+
+ mServer = new RemotePlaybackHTTPServer(mItemLocation);
+ mServer.start();
+ mRemotePlaybackClient = new RemotePlaybackClient(this, route);
+
+ String ip = mServer.getIPAddress(true);
+ if (ip == null)
+ throw new IllegalStateException("Cannot get device's IP address.");
+
+ mState = State.PLAYING;
+ mPlayPause.setBackgroundResource(R.drawable.ic_pause_circle_big_o);
+ mRouteChooser.setVisibility(ImageButton.GONE);
+
+ mRemotePlaybackClient.play(Uri.parse("http://" + ip + ":4212/video"),
+ "video/mp4", new Bundle(), 0, new Bundle(), new ItemActionCallback() {
+
+ @Override
+ public void onResult(Bundle data, String sessionId,
+ MediaSessionStatus sessionStatus,
+ String itemId, MediaItemStatus itemStatus) {
+ Log.d(TAG, "Playback command successfully sent for item: "
+ + itemId + " - " + sessionId);
+ }
+
+ @Override
+ public void onError(String error, int code, Bundle data) {
+ Log.d(TAG, "Playback command error: "+ code +" - "+ error);
+ stop();
+ }
+ });
+ }
+
+
+ private void stop() {
+ if (mRemotePlaybackClient != null) {
+ mRemotePlaybackClient.stop(new Bundle(), new SessionActionCallback() {});
+ mMediaRouter.removeRemoteControlClient(mRemotePlaybackClient);
+ mRemotePlaybackClient.release();
+ mRemotePlaybackClient = null;
+ mServer.stopServer();
+ }
+ mState = State.STOPED;
+ mPlayPause.setBackgroundResource(R.drawable.ic_play_circle_big_o);
+ mRouteChooser.setVisibility(ImageButton.VISIBLE);
+ }
+
+
+ private void pause() {
+ mRemotePlaybackClient.pause(new Bundle(), new SessionActionCallback() {});
+ mState = State.PAUSED;
+ mPlayPause.setBackgroundResource(R.drawable.ic_play_circle_big_o);
+ }
+
+
+ private void resume() {
+ mRemotePlaybackClient.resume(new Bundle(), new SessionActionCallback() {});
+ mState = State.PLAYING;
+ mPlayPause.setBackgroundResource(R.drawable.ic_pause_circle_big_o);
+ }
+
+
+ public void playPause(View v) {
+ switch (mState) {
+ case STOPED:
+ play(mRoute);
+ break;
+ case PLAYING:
+ pause();
+ break;
+ case PAUSED:
+ resume();
+ break;
+ }
+ }
+
+
+ public void showRouteChooser(View v) {
+ MediaRouteChooserDialog d = new MediaRouteChooserDialog(this);
+ d.setRouteSelector(mSelector);
+ d.show();
+ }
+
+}
--
1.9.1
More information about the Android
mailing list