OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.media.remote; | 5 package org.chromium.chrome.browser.media.remote; |
6 | 6 |
7 import android.app.PendingIntent; | 7 import android.app.PendingIntent; |
8 import android.content.BroadcastReceiver; | 8 import android.content.BroadcastReceiver; |
9 import android.content.Context; | 9 import android.content.Context; |
10 import android.content.Intent; | 10 import android.content.Intent; |
11 import android.content.IntentFilter; | 11 import android.content.IntentFilter; |
12 import android.net.Uri; | 12 import android.net.Uri; |
13 import android.os.Bundle; | 13 import android.os.Bundle; |
14 import android.os.SystemClock; | 14 import android.os.SystemClock; |
15 import android.support.v7.media.MediaControlIntent; | 15 import android.support.v7.media.MediaControlIntent; |
16 import android.support.v7.media.MediaItemMetadata; | 16 import android.support.v7.media.MediaItemMetadata; |
17 import android.support.v7.media.MediaItemStatus; | 17 import android.support.v7.media.MediaItemStatus; |
18 import android.support.v7.media.MediaRouteSelector; | 18 import android.support.v7.media.MediaRouteSelector; |
19 import android.support.v7.media.MediaRouter; | 19 import android.support.v7.media.MediaRouter; |
20 import android.support.v7.media.MediaRouter.RouteInfo; | 20 import android.support.v7.media.MediaRouter.RouteInfo; |
21 import android.support.v7.media.MediaSessionStatus; | 21 import android.support.v7.media.MediaSessionStatus; |
22 import android.util.Log; | 22 import android.util.Log; |
23 import android.widget.Toast; | 23 import android.widget.Toast; |
24 | 24 |
25 import com.google.android.gms.cast.CastMediaControlIntent; | 25 import com.google.android.gms.cast.CastMediaControlIntent; |
26 | 26 |
27 import org.apache.http.Header; | |
28 import org.chromium.base.ApplicationState; | 27 import org.chromium.base.ApplicationState; |
29 import org.chromium.base.ApplicationStatus; | 28 import org.chromium.base.ApplicationStatus; |
30 import org.chromium.base.CommandLine; | 29 import org.chromium.base.CommandLine; |
31 import org.chromium.chrome.ChromeSwitches; | 30 import org.chromium.chrome.ChromeSwitches; |
32 import org.chromium.chrome.R; | 31 import org.chromium.chrome.R; |
33 import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; | 32 import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState; |
34 | 33 |
35 import java.net.URI; | 34 import java.net.URI; |
36 import java.net.URISyntaxException; | 35 import java.net.URISyntaxException; |
36 import java.util.List; | |
37 import java.util.Map; | |
37 | 38 |
38 import javax.annotation.Nullable; | 39 import javax.annotation.Nullable; |
39 | 40 |
40 /** | 41 /** |
41 * Class that abstracts all communication to and from the Android MediaRoutes. T his class is | 42 * Class that abstracts all communication to and from the Android MediaRoutes. T his class is |
42 * responsible for connecting to the MRs as well as sending commands and receivi ng status updates | 43 * responsible for connecting to the MRs as well as sending commands and receivi ng status updates |
43 * from the remote player. | 44 * from the remote player. |
44 * | 45 * |
45 * We have three main scenarios for Cast: | 46 * We have three main scenarios for Cast: |
46 * | 47 * |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 void onError(String message, Bundle data); | 87 void onError(String message, Bundle data); |
87 } | 88 } |
88 | 89 |
89 private static final String TAG = "DefaultMediaRouteController"; | 90 private static final String TAG = "DefaultMediaRouteController"; |
90 | 91 |
91 private static final String ACTION_RECEIVE_SESSION_STATUS_UPDATE = | 92 private static final String ACTION_RECEIVE_SESSION_STATUS_UPDATE = |
92 "com.google.android.apps.chrome.videofling.RECEIVE_SESSION_STATUS_UP DATE"; | 93 "com.google.android.apps.chrome.videofling.RECEIVE_SESSION_STATUS_UP DATE"; |
93 private static final String ACTION_RECEIVE_MEDIA_STATUS_UPDATE = | 94 private static final String ACTION_RECEIVE_MEDIA_STATUS_UPDATE = |
94 "com.google.android.apps.chrome.videofling.RECEIVE_MEDIA_STATUS_UPDA TE"; | 95 "com.google.android.apps.chrome.videofling.RECEIVE_MEDIA_STATUS_UPDA TE"; |
95 private static final String MIME_TYPE = "video/mp4"; | 96 private static final String MIME_TYPE = "video/mp4"; |
97 private static final String CORS_HEADER_NAME = "Access-Control-Allow-Origin" ; | |
96 | 98 |
97 private boolean mDebug; | 99 private boolean mDebug; |
98 private String mCurrentSessionId; | 100 private String mCurrentSessionId; |
99 private String mCurrentItemId; | 101 private String mCurrentItemId; |
100 private int mStreamPositionTimestamp; | 102 private int mStreamPositionTimestamp; |
101 private int mLastKnownStreamPosition; | 103 private int mLastKnownStreamPosition; |
102 private int mStreamDuration; | 104 private int mStreamDuration; |
103 private boolean mSeeking; | 105 private boolean mSeeking; |
104 private final String mIntentCategory; | 106 private final String mIntentCategory; |
105 private PendingIntent mSessionStatusUpdateIntent; | 107 private PendingIntent mSessionStatusUpdateIntent; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 public Uri getUri() { | 151 public Uri getUri() { |
150 return mLocalVideoUri; | 152 return mLocalVideoUri; |
151 } | 153 } |
152 | 154 |
153 @Override | 155 @Override |
154 public String getCookies() { | 156 public String getCookies() { |
155 return mLocalVideoCookies; | 157 return mLocalVideoCookies; |
156 } | 158 } |
157 | 159 |
158 @Override | 160 @Override |
159 public void setUri(Uri uri, Header[] headers) { | 161 public void setUri(Uri uri, Map<String, List<String>> headers) { |
160 if (canPlayMedia(uri, headers)) { | 162 if (canPlayMedia(uri, headers)) { |
161 mLocalVideoUri = uri; | 163 mLocalVideoUri = uri; |
162 playMedia(); | 164 playMedia(); |
163 return; | 165 return; |
164 } | 166 } |
165 mLocalVideoUri = null; | 167 mLocalVideoUri = null; |
166 showMessageToast( | 168 showMessageToast( |
167 getContext().getString(R.string.cast_permission_erro r_playing_video)); | 169 getContext().getString(R.string.cast_permission_erro r_playing_video)); |
168 release(); | 170 release(); |
169 } | 171 } |
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1040 if (mMediaUrlResolver != null) mMediaUrlResolver.cancel(true); | 1042 if (mMediaUrlResolver != null) mMediaUrlResolver.cancel(true); |
1041 | 1043 |
1042 // Create a new MediaUrlResolver since the previous one may still be run ning despite the | 1044 // Create a new MediaUrlResolver since the previous one may still be run ning despite the |
1043 // cancel() call. | 1045 // cancel() call. |
1044 mMediaUrlResolver = new MediaUrlResolver(getContext(), mMediaUrlResolver Delegate); | 1046 mMediaUrlResolver = new MediaUrlResolver(getContext(), mMediaUrlResolver Delegate); |
1045 | 1047 |
1046 mStartPositionMillis = startPositionMillis; | 1048 mStartPositionMillis = startPositionMillis; |
1047 mMediaUrlResolver.execute(); | 1049 mMediaUrlResolver.execute(); |
1048 } | 1050 } |
1049 | 1051 |
1050 private boolean canPlayMedia(Uri uri, Header[] headers) { | 1052 private boolean canPlayMedia(Uri uri, Map<String, List<String>> headers) { |
whywhat
2015/03/30 15:51:34
As I explain in the other comment I'd rather move
aberent
2015/03/30 17:24:04
Done.
| |
1051 if (uri == Uri.EMPTY) return false; | 1053 if (uri == Uri.EMPTY) return false; |
1052 | 1054 |
1053 // HLS media requires Cors headers. Since these are the only ones | 1055 // HLS media requires Cors headers. Since these are the only ones |
1054 // sent now we can just check that headers is not empty but | 1056 // sent now we can just check that headers is not empty but |
1055 // if more headers are added we should be more strict in the check. | 1057 // if more headers are added we should be more strict in the check. |
1056 if ((headers == null || headers.length == 0) && isEnhancedMedia(uri)) { | 1058 if ((headers == null || !headers.containsKey(CORS_HEADER_NAME)) && isEnh ancedMedia(uri)) { |
1057 if (mDebug) Log.d(TAG, "HLS stream without CORs header: " + uri); | 1059 if (mDebug) Log.d(TAG, "HLS stream without CORs header: " + uri); |
1058 return false; | 1060 return false; |
1059 } | 1061 } |
1060 return true; | 1062 return true; |
1061 } | 1063 } |
1062 | 1064 |
1063 private void playMedia() { | 1065 private void playMedia() { |
1064 String title = getMediaStateListener().getTitle(); | 1066 String title = getMediaStateListener().getTitle(); |
1065 playUri(mLocalVideoUri, title, mStartPositionMillis); | 1067 playUri(mLocalVideoUri, title, mStartPositionMillis); |
1066 } | 1068 } |
(...skipping 25 matching lines...) Expand all Loading... | |
1092 return SMOOTHSTREAM_MEDIA; | 1094 return SMOOTHSTREAM_MEDIA; |
1093 } | 1095 } |
1094 return UNKNOWN_MEDIA; | 1096 return UNKNOWN_MEDIA; |
1095 } | 1097 } |
1096 | 1098 |
1097 private boolean isEnhancedMedia(Uri videoUri) { | 1099 private boolean isEnhancedMedia(Uri videoUri) { |
1098 int mediaType = getMediaType(videoUri); | 1100 int mediaType = getMediaType(videoUri); |
1099 return mediaType == HLS_MEDIA || mediaType == DASH_MEDIA || mediaType == SMOOTHSTREAM_MEDIA; | 1101 return mediaType == HLS_MEDIA || mediaType == DASH_MEDIA || mediaType == SMOOTHSTREAM_MEDIA; |
1100 } | 1102 } |
1101 } | 1103 } |
OLD | NEW |