| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #ifndef MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ | 5 #ifndef MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ |
| 6 #define MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ | 6 #define MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ |
| 7 | 7 |
| 8 #include <jni.h> | 8 #include <jni.h> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/android/scoped_java_ref.h" | 12 #include "base/android/scoped_java_ref.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/memory/weak_ptr.h" |
| 14 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "base/timer.h" |
| 18 #include "media/base/android/media_player_listener.h" |
| 15 | 19 |
| 16 namespace media { | 20 namespace media { |
| 17 | 21 |
| 22 class CookieGetter; |
| 23 class MediaPlayerBridgeManager; |
| 24 |
| 18 // This class serves as a bridge for native code to call java functions inside | 25 // This class serves as a bridge for native code to call java functions inside |
| 19 // android mediaplayer class. For more information on android mediaplayer, check | 26 // android mediaplayer class. For more information on android mediaplayer, check |
| 20 // http://developer.android.com/reference/android/media/MediaPlayer.html | 27 // http://developer.android.com/reference/android/media/MediaPlayer.html |
| 21 // To use this class, follow the state diagram listed in the above url. | 28 // The actual android mediaplayer instance is created lazily when Start(), |
| 22 // Here is the normal work flow for this class: | 29 // Pause(), SeekTo() gets called. As a result, media information may not |
| 23 // 1. Call SetDataSource() to set the media url. | 30 // be available until one of those operations is performed. After that, we |
| 24 // 2. Call Prepare() to prepare the player for playback. This is a non | 31 // will cache those information in case the mediaplayer gets released. |
| 25 // blocking call. | |
| 26 // 3. When Prepare() succeeds, OnMediaPrepared() will get called. | |
| 27 // 4. Call Start(), Pause(), SeekTo() to play/pause/seek the media. | |
| 28 class MediaPlayerBridge { | 32 class MediaPlayerBridge { |
| 29 public: | 33 public: |
| 30 // Error types for MediaErrorCB. | 34 // Error types for MediaErrorCB. |
| 31 enum MediaErrorType { | 35 enum MediaErrorType { |
| 32 MEDIA_ERROR_UNKNOWN, | 36 MEDIA_ERROR_UNKNOWN, |
| 33 MEDIA_ERROR_SERVER_DIED, | 37 MEDIA_ERROR_SERVER_DIED, |
| 34 MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK, | 38 MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK, |
| 35 MEDIA_ERROR_INVALID_CODE, | 39 MEDIA_ERROR_INVALID_CODE, |
| 36 }; | 40 }; |
| 37 | 41 |
| 38 // Info types for MediaInfoCB. | 42 // Callback when error happens. Args: player ID, error type. |
| 39 enum MediaInfoType { | 43 typedef base::Callback<void(int, int)> MediaErrorCB; |
| 40 MEDIA_INFO_UNKNOWN, | |
| 41 MEDIA_INFO_VIDEO_TRACK_LAGGING, | |
| 42 MEDIA_INFO_BUFFERING_START, | |
| 43 MEDIA_INFO_BUFFERING_END, | |
| 44 MEDIA_INFO_BAD_INTERLEAVING, | |
| 45 MEDIA_INFO_NOT_SEEKABLE, | |
| 46 MEDIA_INFO_METADATA_UPDATE, | |
| 47 }; | |
| 48 | 44 |
| 49 // Callback when video info is received. Args: info type. | 45 // Callback when video size has changed. Args: player ID, width, height. |
| 50 typedef base::Callback<void(int)> MediaInfoCB; | 46 typedef base::Callback<void(int, int, int)> VideoSizeChangedCB; |
| 51 | 47 |
| 52 // Callback when error happens. Args: error type. | 48 // Callback when buffering has changed. Args: player ID, percentage |
| 53 typedef base::Callback<void(int)> MediaErrorCB; | 49 // of the media. |
| 50 typedef base::Callback<void(int, int)> BufferingUpdateCB; |
| 54 | 51 |
| 55 // Callback when video size has changed. Args: width, height. | 52 // Callback when player got prepared. Args: player ID, duration of the media. |
| 56 typedef base::Callback<void(int,int)> VideoSizeChangedCB; | 53 typedef base::Callback<void(int, base::TimeDelta)> MediaPreparedCB; |
| 57 | 54 |
| 58 // Callback when buffering has changed. Args: percentage of the media. | 55 // Callbacks when seek completed. Args: player ID, current time. |
| 59 typedef base::Callback<void(int)> BufferingUpdateCB; | 56 typedef base::Callback<void(int, base::TimeDelta)> SeekCompleteCB; |
| 60 | 57 |
| 61 MediaPlayerBridge(); | 58 // Callbacks when playback completed. Args: player ID. |
| 59 typedef base::Callback<void(int)> PlaybackCompleteCB; |
| 60 |
| 61 // Callback when time update messages need to be sent. Args: player ID, |
| 62 // current time. |
| 63 typedef base::Callback<void(int, base::TimeDelta)> TimeUpdateCB; |
| 64 |
| 65 // Construct a MediaPlayerBridge object with all the needed media player |
| 66 // callbacks. This object needs to call |manager|'s RequestMediaResources() |
| 67 // before decoding the media stream. This allows |manager| to track |
| 68 // unused resources and free them when needed. On the other hand, it needs |
| 69 // to call ReleaseMediaResources() when it is done with decoding. |
| 70 MediaPlayerBridge(int player_id, |
| 71 const std::string& url, |
| 72 const std::string& first_party_for_cookies, |
| 73 CookieGetter* cookies_getter, |
| 74 bool hide_url_log, |
| 75 MediaPlayerBridgeManager* manager, |
| 76 const MediaErrorCB& media_error_cb, |
| 77 const VideoSizeChangedCB& video_size_changed_cb, |
| 78 const BufferingUpdateCB& buffering_update_cb, |
| 79 const MediaPreparedCB& media_prepared_cb, |
| 80 const PlaybackCompleteCB& playback_complete_cb, |
| 81 const SeekCompleteCB& seek_complete_cb, |
| 82 const TimeUpdateCB& time_update_cb); |
| 62 ~MediaPlayerBridge(); | 83 ~MediaPlayerBridge(); |
| 63 | 84 |
| 64 typedef std::map<std::string, std::string> HeadersMap; | 85 typedef std::map<std::string, std::string> HeadersMap; |
| 65 void SetDataSource(const std::string& url, | |
| 66 const std::string& cookies, | |
| 67 bool hide_url_log); | |
| 68 | 86 |
| 69 void SetVideoSurface(jobject surface); | 87 void SetVideoSurface(jobject surface); |
| 70 | 88 |
| 71 // Prepare the player for playback, asynchronously. When succeeds, | |
| 72 // OnMediaPrepared() will be called. Otherwise, OnMediaError() will | |
| 73 // be called with an error type. | |
| 74 void Prepare(const MediaInfoCB& media_info_cb, | |
| 75 const MediaErrorCB& media_error_cb, | |
| 76 const VideoSizeChangedCB& video_size_changed_cb, | |
| 77 const BufferingUpdateCB& buffering_update_cb, | |
| 78 const base::Closure& media_prepared_cb); | |
| 79 | |
| 80 // Start playing the media. | 89 // Start playing the media. |
| 81 void Start(const base::Closure& playback_complete_cb); | 90 void Start(); |
| 82 | 91 |
| 83 // Pause the media. | 92 // Pause the media. |
| 84 void Pause(); | 93 void Pause(); |
| 85 | 94 |
| 86 // Stop the media playback. Needs to call Prepare() again to play the media. | |
| 87 void Stop(); | |
| 88 | |
| 89 // Seek to a particular position. When succeeds, OnSeekComplete() will be | 95 // Seek to a particular position. When succeeds, OnSeekComplete() will be |
| 90 // called. Otherwise, nothing will happen. | 96 // called. Otherwise, nothing will happen. |
| 91 void SeekTo(base::TimeDelta time, const base::Closure& seek_complete_cb); | 97 void SeekTo(base::TimeDelta time); |
| 92 | 98 |
| 93 // Reset the player. Needs to call SetDataSource() again after this call. | 99 // Release the player resources. |
| 94 void Reset(); | 100 void Release(); |
| 95 | 101 |
| 96 // Set the player volume. | 102 // Set the player volume. |
| 97 void SetVolume(float leftVolume, float rightVolume); | 103 void SetVolume(float leftVolume, float rightVolume); |
| 98 | 104 |
| 99 // Get the media information from the player. | 105 // Get the media information from the player. |
| 100 int GetVideoWidth(); | 106 int GetVideoWidth(); |
| 101 int GetVideoHeight(); | 107 int GetVideoHeight(); |
| 102 base::TimeDelta GetCurrentTime(); | 108 base::TimeDelta GetCurrentTime(); |
| 103 base::TimeDelta GetDuration(); | 109 base::TimeDelta GetDuration(); |
| 104 bool IsPlaying(); | 110 bool IsPlaying(); |
| 105 | 111 |
| 106 // Get metadata from the media. | 112 // Get metadata from the media. |
| 107 void GetMetadata(bool* can_pause, | 113 void GetMetadata(); |
| 108 bool* can_seek_forward, | |
| 109 bool* can_seek_backward); | |
| 110 | 114 |
| 111 // Set the device to stay awake when player is playing. | 115 // Called by the timer to check for current time routinely and generates |
| 112 void SetStayAwakeWhilePlaying(); | 116 // time update events. |
| 117 void DoTimeUpdate(); |
| 113 | 118 |
| 114 // Called by the Java MediaPlayerListener and mirrored to corresponding | 119 // Called by the MediaPlayerListener and mirrored to corresponding |
| 115 // callbacks. | 120 // callbacks. |
| 116 void OnMediaError(JNIEnv* /* env */, jobject /* obj */, jint error_type); | 121 void OnMediaError(int error_type); |
| 117 void OnMediaInfo(JNIEnv* /* env */, jobject /* obj */, jint info_type); | 122 void OnVideoSizeChanged(int width, int height); |
| 118 void OnVideoSizeChanged(JNIEnv* /* env */, jobject /* obj */, | 123 void OnBufferingUpdate(int percent); |
| 119 jint width, jint height); | 124 void OnPlaybackComplete(); |
| 120 void OnBufferingUpdate(JNIEnv* /* env */, jobject /* obj */, jint percent); | 125 void OnSeekComplete(); |
| 121 void OnPlaybackComplete(JNIEnv* /* env */, jobject /* obj */); | 126 void OnMediaPrepared(); |
| 122 void OnSeekComplete(JNIEnv* /* env */, jobject /* obj */); | |
| 123 void OnMediaPrepared(JNIEnv* /* env */, jobject /* obj */); | |
| 124 | 127 |
| 125 // Register MediaPlayerListener in the system library loader. | 128 // Prepare the player for playback, asynchronously. When succeeds, |
| 126 static bool RegisterMediaPlayerListener(JNIEnv* env); | 129 // OnMediaPrepared() will be called. Otherwise, OnMediaError() will |
| 130 // be called with an error type. |
| 131 void Prepare(); |
| 132 |
| 133 // Callback function passed to |cookies_retriever_|. |
| 134 void GetCookiesCallback(const std::string& cookies); |
| 135 |
| 136 int player_id() { return player_id_; } |
| 137 bool can_pause() { return can_pause_; } |
| 138 bool can_seek_forward() { return can_seek_forward_; } |
| 139 bool can_seek_backward() { return can_seek_backward_; } |
| 140 bool prepared() { return prepared_; } |
| 127 | 141 |
| 128 private: | 142 private: |
| 129 void CallVoidMethod(std::string method_name); | 143 void CallVoidMethod(std::string method_name); |
| 130 int CallIntMethod(std::string method_name); | 144 int CallIntMethod(std::string method_name); |
| 131 | 145 |
| 146 // Create the actual android media player. |
| 147 void InitializePlayer(); |
| 148 |
| 149 // Functions that implements media player control. |
| 150 void StartInternal(); |
| 151 void PauseInternal(); |
| 152 void SeekInternal(base::TimeDelta time); |
| 153 |
| 132 // Callbacks when events are received. | 154 // Callbacks when events are received. |
| 133 MediaInfoCB media_info_cb_; | |
| 134 MediaErrorCB media_error_cb_; | 155 MediaErrorCB media_error_cb_; |
| 135 VideoSizeChangedCB video_size_changed_cb_; | 156 VideoSizeChangedCB video_size_changed_cb_; |
| 136 BufferingUpdateCB buffering_update_cb_; | 157 BufferingUpdateCB buffering_update_cb_; |
| 137 base::Closure playback_complete_cb_; | 158 MediaPreparedCB media_prepared_cb_; |
| 138 base::Closure seek_complete_cb_; | 159 PlaybackCompleteCB playback_complete_cb_; |
| 139 base::Closure media_prepared_cb_; | 160 SeekCompleteCB seek_complete_cb_; |
| 161 |
| 162 // Callbacks when timer events are received. |
| 163 TimeUpdateCB time_update_cb_; |
| 164 |
| 165 // Player ID assigned to this player. |
| 166 int player_id_; |
| 167 |
| 168 // Whether the player is prepared for playback. |
| 169 bool prepared_; |
| 170 |
| 171 // Pending play event while player is preparing. |
| 172 bool pending_play_; |
| 173 |
| 174 // Pending seek time while player is preparing. |
| 175 base::TimeDelta pending_seek_; |
| 176 |
| 177 // Url for playback. |
| 178 std::string url_; |
| 179 |
| 180 // First party url for cookies. |
| 181 std::string first_party_for_cookies_; |
| 182 |
| 183 // Whether cookies are available. |
| 184 bool has_cookies_; |
| 185 |
| 186 // Hide url log from media player. |
| 187 bool hide_url_log_; |
| 188 |
| 189 // Stats about the media. |
| 190 base::TimeDelta duration_; |
| 191 int width_; |
| 192 int height_; |
| 193 |
| 194 // Meta data about actions can be taken. |
| 195 bool can_pause_; |
| 196 bool can_seek_forward_; |
| 197 bool can_seek_backward_; |
| 198 |
| 199 // Cookies for |url_| |
| 200 std::string cookies_; |
| 201 |
| 202 // Resource manager for all the media players. |
| 203 MediaPlayerBridgeManager* manager_; |
| 204 |
| 205 // Object for retrieving cookies for this media player. |
| 206 scoped_ptr<CookieGetter> cookie_getter_; |
| 140 | 207 |
| 141 // Java MediaPlayer class and instance. | 208 // Java MediaPlayer class and instance. |
| 142 base::android::ScopedJavaGlobalRef<jclass> j_media_player_class_; | 209 base::android::ScopedJavaGlobalRef<jclass> j_media_player_class_; |
| 143 base::android::ScopedJavaGlobalRef<jobject> j_media_player_; | 210 base::android::ScopedJavaGlobalRef<jobject> j_media_player_; |
| 144 | 211 |
| 212 base::RepeatingTimer<MediaPlayerBridge> time_update_timer_; |
| 213 |
| 214 // Weak pointer passed to |listener_| for callbacks. |
| 215 base::WeakPtrFactory<MediaPlayerBridge> weak_this_; |
| 216 |
| 217 // Listener object that listens to all the media player events. |
| 218 MediaPlayerListener listener_; |
| 219 |
| 145 DISALLOW_COPY_AND_ASSIGN(MediaPlayerBridge); | 220 DISALLOW_COPY_AND_ASSIGN(MediaPlayerBridge); |
| 146 }; | 221 }; |
| 147 | 222 |
| 148 } // namespace media | 223 } // namespace media |
| 149 | 224 |
| 150 #endif // MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ | 225 #endif // MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ |
| OLD | NEW |