19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huberimport android.content.BroadcastReceiver; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 22d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huberimport android.content.Intent; 23d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huberimport android.content.IntentFilter; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 25d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huberimport android.net.Proxy; 26d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huberimport android.net.ProxyProperties; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 29484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport android.os.HandlerThread; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 3220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Cataniaimport android.os.Parcel; 3341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kangimport android.os.Parcelable; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 35484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport android.os.Process; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceHolder; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap; 41cc562a3576a6a8096626387472e05e8bee03352aGlenn Kastenimport android.graphics.SurfaceTexture; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.AudioManager; 431c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnarimport android.media.MediaFormat; 443d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnarimport android.media.MediaTimeProvider; 453d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnarimport android.media.MediaTimeProvider.OnMediaTimeListener; 46484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport android.media.SubtitleController; 4783ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhangimport android.media.SubtitleData; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49e00b6f3a57d4b480ce674468de93555269bbd71aJames Dongimport java.io.File; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 51e00b6f3a57d4b480ce674468de93555269bbd71aJames Dongimport java.io.FileInputStream; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 53484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport java.io.InputStream; 54484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport java.lang.Runnable; 55720aa282791ef9405d39a15f419a41ab24f11e30John Grossmanimport java.net.InetSocketAddress; 56256430093679e1d62b54fb0c852126e54d162f6fAndreas Huberimport java.util.Map; 57484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarimport java.util.Scanner; 589193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Cataniaimport java.util.Set; 593d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnarimport java.util.Vector; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer class can be used to control playback 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of audio/video files and streams. An example on how to use the methods in 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this class can be found in {@link android.widget.VideoView}. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Topics covered here are: 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><a href="#StateDiagram">State Diagram</a> 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><a href="#Permissions">Permissions</a> 729ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * <li><a href="#Callbacks">Register informational and error callbacks</a> 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol> 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7561fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <div class="special reference"> 7661fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <h3>Developer Guides</h3> 7761fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <p>For more information about how to use MediaPlayer, read the 7861fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p> 7961fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * </div> 8061fd1e8d8c3ccf2d6b7d4af1c19e8f0988d5a1ecJoe Fernandez * 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="StateDiagram"></a> 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>State Diagram</h3> 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Playback control of audio/video files and streams is managed as a state 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * machine. The following diagram shows the life cycle and the states of a 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer object driven by the supported playback control operations. 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ovals represent the states a MediaPlayer object may reside 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in. The arcs represent the playback control operations that drive the object 8932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * state transition. There are two types of arcs. The arcs with a single arrow 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * head represent synchronous method calls, while those with 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a double arrow head represent asynchronous method calls.</p> 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><img src="../../../images/mediaplayer_state_diagram.gif" 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * alt="MediaPlayer State diagram" 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * border="0" /></p> 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>From this state diagram, one can see that a MediaPlayer object has the 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * following states:</p> 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 10032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>When a MediaPlayer object is just created using <code>new</code> or 10132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * after {@link #reset()} is called, it is in the <em>Idle</em> state; and after 10232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #release()} is called, it is in the <em>End</em> state. Between these 10332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * two states is the life cycle of the MediaPlayer object. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 10532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>There is a subtle but important difference between a newly constructed 10632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * MediaPlayer object and the MediaPlayer object after {@link #reset()} 10732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * is called. It is a programming error to invoke methods such 10832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * as {@link #getCurrentPosition()}, 10932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #getDuration()}, {@link #getVideoHeight()}, 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getVideoWidth()}, {@link #setAudioStreamType(int)}, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setLooping(boolean)}, 11232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()}, 11332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or 11432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these 11532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * methods is called right after a MediaPlayer object is constructed, 11632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the user supplied callback method OnErrorListener.onError() won't be 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called by the internal player engine and the object state remains 11832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * unchanged; but if these methods are called right after {@link #reset()}, 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the user supplied callback method OnErrorListener.onError() will be 12032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * invoked by the internal player engine and the object will be 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transfered to the <em>Error</em> state. </li> 12232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>It is also recommended that once 12332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * a MediaPlayer object is no longer being used, call {@link #release()} immediately 12432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * so that resources used by the internal player engine associated with the 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer object can be released immediately. Resource may include 12632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * singleton resources such as hardware acceleration components and 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * failure to call {@link #release()} may cause subsequent instances of 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer objects to fallback to software implementations or fail 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * altogether. Once the MediaPlayer 13032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object is in the <em>End</em> state, it can no longer be used and 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * there is no way to bring it back to any other state. </li> 13232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>Furthermore, 13332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the MediaPlayer objects created using <code>new</code> is in the 13432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <em>Idle</em> state, while those created with one 13532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * of the overloaded convenient <code>create</code> methods are <em>NOT</em> 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the <em>Idle</em> state. In fact, the objects are in the <em>Prepared</em> 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state if the creation using <code>create</code> method is successful. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>In general, some playback control operation may fail due to various 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reasons, such as unsupported audio/video format, poorly interleaved 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * audio/video, resolution too high, streaming timeout, and the like. 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Thus, error reporting and recovery is an important concern under 14532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * these circumstances. Sometimes, due to programming errors, invoking a playback 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * control operation in an invalid state may also occur. Under all these 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * error conditions, the internal player engine invokes a user supplied 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OnErrorListener.onError() method if an OnErrorListener has been 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * registered beforehand via 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setOnErrorListener(android.media.MediaPlayer.OnErrorListener)}. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 15232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>It is important to note that once an error occurs, the 15332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * MediaPlayer object enters the <em>Error</em> state (except as noted 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * above), even if an error listener has not been registered by the application.</li> 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>In order to reuse a MediaPlayer object that is in the <em> 15632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * Error</em> state and recover from the error, 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #reset()} can be called to restore the object to its <em>Idle</em> 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state.</li> 15932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>It is good programming practice to have your application 16032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * register a OnErrorListener to look out for error notifications from 16132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the internal player engine.</li> 162c6f8ea4cf26aadc0da765585d37f7850596af6dehugh kennedy * <li>IllegalStateException is 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * thrown to prevent programming errors such as calling {@link #prepare()}, 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #prepareAsync()}, or one of the overloaded <code>setDataSource 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </code> methods in an invalid state. </li> 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Calling 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setDataSource(FileDescriptor)}, or 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setDataSource(String)}, or 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setDataSource(Context, Uri)}, or 17232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #setDataSource(FileDescriptor, long, long)} transfers a 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer object in the <em>Idle</em> state to the 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>Initialized</em> state. 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 17632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>An IllegalStateException is thrown if 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setDataSource() is called in any other state.</li> 17832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>It is good programming 17932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * practice to always look out for <code>IllegalArgumentException</code> 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and <code>IOException</code> that may be thrown from the overloaded 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>setDataSource</code> methods.</li> 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>A MediaPlayer object must first enter the <em>Prepared</em> state 18532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * before playback can be started. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>There are two ways (synchronous vs. 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * asynchronous) that the <em>Prepared</em> state can be reached: 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * either a call to {@link #prepare()} (synchronous) which 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transfers the object to the <em>Prepared</em> state once the method call 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns, or a call to {@link #prepareAsync()} (asynchronous) which 19232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * first transfers the object to the <em>Preparing</em> state after the 19332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * call returns (which occurs almost right way) while the internal 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * player engine continues working on the rest of preparation work 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the internal player engine then calls a user supplied callback method, 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * onPrepared() of the OnPreparedListener interface, if an 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OnPreparedListener is registered beforehand via {@link 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * #setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)}.</li> 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>It is important to note that 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the <em>Preparing</em> state is a transient state, and the behavior 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of calling any method with side effect while a MediaPlayer object is 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the <em>Preparing</em> state is undefined.</li> 20432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>An IllegalStateException is 20532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * thrown if {@link #prepare()} or {@link #prepareAsync()} is called in 20632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * any other state.</li> 20732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>While in the <em>Prepared</em> state, properties 20832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * such as audio/sound volume, screenOnWhilePlaying, looping can be 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * adjusted by invoking the corresponding set methods.</li> 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 21232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>To start the playback, {@link #start()} must be called. After 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #start()} returns successfully, the MediaPlayer object is in the 21432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <em>Started</em> state. {@link #isPlaying()} can be called to test 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whether the MediaPlayer object is in the <em>Started</em> state. 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>While in the <em>Started</em> state, the internal player engine calls 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback 21932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * method if a OnBufferingUpdateListener has been registered beforehand 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * via {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This callback allows applications to keep track of the buffering status 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * while streaming audio/video.</li> 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Calling {@link #start()} has not effect 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on a MediaPlayer object that is already in the <em>Started</em> state.</li> 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Playback can be paused and stopped, and the current playback position 22832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * can be adjusted. Playback can be paused via {@link #pause()}. When the call to 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #pause()} returns, the MediaPlayer object enters the 23032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <em>Paused</em> state. Note that the transition from the <em>Started</em> 23132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * state to the <em>Paused</em> state and vice versa happens 23232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * asynchronously in the player engine. It may take some time before 23332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the state is updated in calls to {@link #isPlaying()}, and it can be 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a number of seconds in the case of streamed content. 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 23632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>Calling {@link #start()} to resume playback for a paused 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer object, and the resumed playback 23832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * position is the same as where it was paused. When the call to 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #start()} returns, the paused MediaPlayer object goes back to 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the <em>Started</em> state.</li> 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Calling {@link #pause()} has no effect on 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a MediaPlayer object that is already in the <em>Paused</em> state.</li> 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 24532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>Calling {@link #stop()} stops playback and causes a 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MediaPlayer in the <em>Started</em>, <em>Paused</em>, <em>Prepared 24732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * </em> or <em>PlaybackCompleted</em> state to enter the 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>Stopped</em> state. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 25032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>Once in the <em>Stopped</em> state, playback cannot be started 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * until {@link #prepare()} or {@link #prepareAsync()} are called to set 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the MediaPlayer object to the <em>Prepared</em> state again.</li> 25332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>Calling {@link #stop()} has no effect on a MediaPlayer 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object that is already in the <em>Stopped</em> state.</li> 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 25732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <li>The playback position can be adjusted with a call to 25832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * {@link #seekTo(int)}. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Although the asynchronuous {@link #seekTo(int)} 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call returns right way, the actual seek operation may take a while to 26232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * finish, especially for audio/video being streamed. When the actual 26332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * seek operation completes, the internal player engine calls a user 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener 26532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * has been registered beforehand via 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li> 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Please 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * note that {@link #seekTo(int)} can also be called in the other states, 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </em> state.</li> 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Furthermore, the actual current playback position 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can be retrieved with a call to {@link #getCurrentPosition()}, which 27332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * is helpful for applications such as a Music player that need to keep 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * track of the playback progress.</li> 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>When the playback reaches the end of stream, the playback completes. 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>If the looping mode was being set to <var>true</var>with 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setLooping(boolean)}, the MediaPlayer object shall remain in 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the <em>Started</em> state.</li> 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>If the looping mode was set to <var>false 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </var>, the player engine calls a user supplied callback method, 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OnCompletion.onCompletion(), if a OnCompletionListener is registered 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * beforehand via {@link #setOnCompletionListener(OnCompletionListener)}. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The invoke of the callback signals that the object is now in the <em> 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted</em> state.</li> 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>While in the <em>PlaybackCompleted</em> 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state, calling {@link #start()} can restart the playback from the 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * beginning of the audio/video source.</li> 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="Valid_and_Invalid_States"></a> 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Valid and invalid states</h3> 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <table border="0" cellspacing="0" cellpadding="0"> 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>Method Name </p></td> 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Valid Sates </p></td> 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Invalid States </p></td> 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Comments </p></td></tr> 30217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <tr><td>attachAuxEffect </p></td> 30317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td> 30417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{Idle, Error} </p></td> 30517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>This method must be called after setDataSource. 30617cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * Calling it does not change the object state. </p></td></tr> 30717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <tr><td>getAudioSessionId </p></td> 30817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>any </p></td> 30917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{} </p></td> 31017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>This method can be called in any state and calling it does not change 31117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * the object state. </p></td></tr> 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>getCurrentPosition </p></td> 31332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped, 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted} </p></td> 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Successful invoke of this method in a valid state does not change the 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state. Calling this method in an invalid state transfers the object 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the <em>Error</em> state. </p></td></tr> 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>getDuration </p></td> 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td> 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Initialized, Error} </p></td> 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Successful invoke of this method in a valid state does not change the 32332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * state. Calling this method in an invalid state transfers the object 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the <em>Error</em> state. </p></td></tr> 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>getVideoHeight </p></td> 32632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped, 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Successful invoke of this method in a valid state does not change the 33032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * state. Calling this method in an invalid state transfers the object 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the <em>Error</em> state. </p></td></tr> 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>getVideoWidth </p></td> 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped, 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 33632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state does not change 33732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the state. Calling this method in an invalid state transfers the 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object to the <em>Error</em> state. </p></td></tr> 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>isPlaying </p></td> 34032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped, 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Successful invoke of this method in a valid state does not change 34432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the state. Calling this method in an invalid state transfers the 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object to the <em>Error</em> state. </p></td></tr> 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>pause </p></td> 347b04c07fb9b105fe55ea261283d0be2c817133d67kmccormick * <td>{Started, Paused, PlaybackCompleted}</p></td> 348b04c07fb9b105fe55ea261283d0be2c817133d67kmccormick * <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td> 34932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 35032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object to the <em>Paused</em> state. Calling this method in an 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state transfers the object to the <em>Error</em> state.</p></td></tr> 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>prepare </p></td> 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Initialized, Stopped} </p></td> 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td> 35532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 35632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object to the <em>Prepared</em> state. Calling this method in an 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state throws an IllegalStateException.</p></td></tr> 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>prepareAsync </p></td> 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Initialized, Stopped} </p></td> 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td> 36132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object to the <em>Preparing</em> state. Calling this method in an 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state throws an IllegalStateException.</p></td></tr> 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>release </p></td> 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>After {@link #release()}, the object is no longer available. </p></td></tr> 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>reset </p></td> 36932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped, 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted, Error}</p></td> 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{}</p></td> 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>After {@link #reset()}, the object is like being just created.</p></td></tr> 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>seekTo </p></td> 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td> 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Initialized, Stopped, Error}</p></td> 37632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state does not change 37732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the state. Calling this method in an invalid state transfers the 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object to the <em>Error</em> state. </p></td></tr> 37917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <tr><td>setAudioSessionId </p></td> 38017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{Idle} </p></td> 38117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, 38217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * Error} </p></td> 38317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>This method must be called in idle state as the audio session ID must be known before 38417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * calling setDataSource. Calling it does not change the object state. </p></td></tr> 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setAudioStreamType </p></td> 38632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused, 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 3899d96354d7055cd165d7d5625990f810f46339e52James Dong * <td>Successful invoke of this method does not change the state. In order for the 3909d96354d7055cd165d7d5625990f810f46339e52James Dong * target audio stream type to become effective, this method must be called before 3919d96354d7055cd165d7d5625990f810f46339e52James Dong * prepare() or prepareAsync().</p></td></tr> 39217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <tr><td>setAuxEffectSendLevel </p></td> 39317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>any</p></td> 39417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>{} </p></td> 39517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * <td>Calling this method does not change the object state. </p></td></tr> 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setDataSource </p></td> 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle} </p></td> 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Error} </p></td> 40032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 40132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object to the <em>Initialized</em> state. Calling this method in an 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state throws an IllegalStateException.</p></td></tr> 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setDisplay </p></td> 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 408b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * <tr><td>setSurface </p></td> 409cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * <td>any </p></td> 410cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * <td>{} </p></td> 411cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * <td>This method can be called in any state and calling it does not change 412cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * the object state. </p></td></tr> 413454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <tr><td>setVideoScalingMode </p></td> 414454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td> 415454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <td>{Idle, Error}</p></td> 416454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <td>Successful invoke of this method does not change the state.</p></td></tr> 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setLooping </p></td> 41832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused, 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 42132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state does not change 42232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * the state. Calling this method in an 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state transfers the object to the <em>Error</em> state.</p></td></tr> 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>isLooping </p></td> 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setOnBufferingUpdateListener </p></td> 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setOnCompletionListener </p></td> 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setOnErrorListener </p></td> 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setOnPreparedListener </p></td> 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setOnSeekCompleteListener </p></td> 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setScreenOnWhilePlaying</></td> 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state. </p></td></tr> 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setVolume </p></td> 46032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused, 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * PlaybackCompleted}</p></td> 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Error}</p></td> 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>Successful invoke of this method does not change the state. 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>setWakeMode </p></td> 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>any </p></td> 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{} </p></td> 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>This method can be called in any state and calling it does not change 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the object state.</p></td></tr> 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>start </p></td> 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td> 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Initialized, Stopped, Error}</p></td> 47232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 47332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object to the <em>Started</em> state. Calling this method in an 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state transfers the object to the <em>Error</em> state.</p></td></tr> 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tr><td>stop </p></td> 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td> 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <td>{Idle, Initialized, Error}</p></td> 47832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * <td>Successful invoke of this method in a valid state transfers the 47932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * object to the <em>Stopped</em> state. Calling this method in an 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * invalid state transfers the object to the <em>Error</em> state.</p></td></tr> 48141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <tr><td>getTrackInfo </p></td> 48241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td> 48341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Idle, Initialized, Error}</p></td> 48441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>Successful invoke of this method does not change the state.</p></td></tr> 4857a9734d769d97470ce6fac0594dd007804d33432James Dong * <tr><td>addTimedTextSource </p></td> 48641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td> 48741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Idle, Initialized, Error}</p></td> 48841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>Successful invoke of this method does not change the state.</p></td></tr> 48941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <tr><td>selectTrack </p></td> 49041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td> 49141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Idle, Initialized, Error}</p></td> 49241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>Successful invoke of this method does not change the state.</p></td></tr> 4937a9734d769d97470ce6fac0594dd007804d33432James Dong * <tr><td>deselectTrack </p></td> 49441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td> 49541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>{Idle, Initialized, Error}</p></td> 49641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <td>Successful invoke of this method does not change the state.</p></td></tr> 497619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </table> 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="Permissions"></a> 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Permissions</h3> 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>One may need to declare a corresponding WAKE_LOCK permission {@link 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.R.styleable#AndroidManifestUsesPermission <uses-permission>} 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * element. 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 506fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission 507fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke * when used with network-based content. 508fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke * 5099ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * <a name="Callbacks"></a> 5109ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * <h3>Callbacks</h3> 5119ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * <p>Applications may want to register for informational and error 5129ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * events in order to be informed of some internal state update and 5139ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * possible runtime errors during playback or streaming. Registration for 5149ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * these events is done by properly setting the appropriate listeners (via calls 5159ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * to 5169ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnPreparedListener(OnPreparedListener)}setOnPreparedListener, 5179ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}setOnVideoSizeChangedListener, 5189ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}setOnSeekCompleteListener, 5199ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnCompletionListener(OnCompletionListener)}setOnCompletionListener, 520d52ad9ca8d36afa76161c61b65a71d70977c0d3fJames Dong * {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}setOnBufferingUpdateListener, 5219ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnInfoListener(OnInfoListener)}setOnInfoListener, 5229ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * {@link #setOnErrorListener(OnErrorListener)}setOnErrorListener, etc). 5239ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * In order to receive the respective callback 5249ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * associated with these listeners, applications are required to create 5259ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * MediaPlayer objects on a thread with its own Looper running (main UI 5269ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * thread by default has a Looper running). 5279ddb7888b4b8c7b1f9e352347d84ae530e47a77dJames Dong * 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnarpublic class MediaPlayer implements SubtitleController.Listener 53032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania{ 5319193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 5329193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Constant to retrieve only the new metadata since the last 5339193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania call. 5349193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 5359193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: add link to getMetadata(boolean, boolean) 5369193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania {@hide} 5379193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 5389193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final boolean METADATA_UPDATE_ONLY = true; 5399193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5409193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 5419193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Constant to retrieve all the metadata. 5429193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 5439193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: add link to getMetadata(boolean, boolean) 5449193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania {@hide} 5459193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 5469193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final boolean METADATA_ALL = false; 5479193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5489193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 5499193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Constant to enable the metadata filter during retrieval. 5509193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 5519193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: add link to getMetadata(boolean, boolean) 5529193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania {@hide} 5539193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 5549193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final boolean APPLY_METADATA_FILTER = true; 5559193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5569193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 5579193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania Constant to disable the metadata filter during retrieval. 5589193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 5599193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: add link to getMetadata(boolean, boolean) 5609193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania {@hide} 5619193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 5629193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final boolean BYPASS_METADATA_FILTER = false; 5639193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.loadLibrary("media_jni"); 5664935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen native_init(); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String TAG = "MediaPlayer"; 57020cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania // Name of the remote interface for the media player. Must be kept 57120cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania // in sync with the 2nd parameter of the IMPLEMENT_META_INTERFACE 57220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania // macro invocation in IMediaPlayer.cpp 57320cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania private final static String IMEDIA_PLAYER = "android.media.IMediaPlayer"; 57432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeContext; // accessed by native methods 5761ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg private int mNativeSurfaceTexture; // accessed by native methods 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mListenerContext; // accessed by native methods 5781ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg private SurfaceHolder mSurfaceHolder; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private EventHandler mEventHandler; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock = null; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mScreenOnWhilePlaying; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStayAwake; 58332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 58532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * Default constructor. Consider using one of the create() methods for 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * synchronously instantiating a MediaPlayer from a Uri or resource. 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When done with the MediaPlayer, you should call {@link #release()}, 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to free the resources. If not released, too many MediaPlayer instances may 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result in an exception.</p> 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MediaPlayer() { 59232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper looper; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((looper = Looper.myLooper()) != null) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventHandler = new EventHandler(this, looper); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((looper = Looper.getMainLooper()) != null) { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventHandler = new EventHandler(this, looper); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventHandler = null; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6023d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeProvider = new TimeProvider(this); 603484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>(); 604484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOpenSubtitleSources = new Vector<InputStream>(); 605484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mInbandSubtitleTracks = new SubtitleTrack[0]; 6063d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Native setup requires a weak reference to our object. 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It's easier to create it here than in C++. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_setup(new WeakReference<MediaPlayer>(this)); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6128b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks 6138b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks /* 6141ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg * Update the MediaPlayer SurfaceTexture. 6151ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg * Call after setting a new display surface. 6168b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks */ 6171ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg private native void _setVideoSurface(Surface surface); 61832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 61941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* Do not change these values (starting with INVOKE_ID) without updating 62041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * their counterparts in include/media/mediaplayer.h! 62141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 62241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang private static final int INVOKE_ID_GET_TRACK_INFO = 1; 62341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE = 2; 62441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3; 62541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang private static final int INVOKE_ID_SELECT_TRACK = 4; 6267a9734d769d97470ce6fac0594dd007804d33432James Dong private static final int INVOKE_ID_DESELECT_TRACK = 5; 627454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong private static final int INVOKE_ID_SET_VIDEO_SCALE_MODE = 6; 62841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 63020cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * Create a request parcel which can be routed to the native media 63120cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * player using {@link #invoke(Parcel, Parcel)}. The Parcel 63220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * returned has the proper InterfaceToken set. The caller should 63320cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * not overwrite that token, i.e it can only append data to the 63420cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * Parcel. 63520cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * 63620cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * @return A parcel suitable to hold a request for the native 63720cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * player. 6382d2cd32cc7293bbb48b0f0e70a0dc7eb05cac9d3Marco Nelissen * {@hide} 63920cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania */ 6402d2cd32cc7293bbb48b0f0e70a0dc7eb05cac9d3Marco Nelissen public Parcel newRequest() { 64120cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania Parcel parcel = Parcel.obtain(); 64220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania parcel.writeInterfaceToken(IMEDIA_PLAYER); 64320cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania return parcel; 64420cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania } 64520cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania 64620cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania /** 64720cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * Invoke a generic method on the native player using opaque 64820cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * parcels for the request and reply. Both payloads' format is a 64920cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * convention between the java caller and the native player. 65020cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * Must be called after setDataSource to make sure a native player 6517a9734d769d97470ce6fac0594dd007804d33432James Dong * exists. On failure, a RuntimeException is thrown. 65220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * 65320cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * @param request Parcel with the data for the extension. The 65420cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * caller must use {@link #newRequest()} to get one. 65520cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * 6564a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @param reply Output parcel with the data returned by the 65720cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * native player. 6582d2cd32cc7293bbb48b0f0e70a0dc7eb05cac9d3Marco Nelissen * {@hide} 65920cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania */ 6602d2cd32cc7293bbb48b0f0e70a0dc7eb05cac9d3Marco Nelissen public void invoke(Parcel request, Parcel reply) { 66120cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania int retcode = native_invoke(request, reply); 66220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania reply.setDataPosition(0); 6637a9734d769d97470ce6fac0594dd007804d33432James Dong if (retcode != 0) { 6647a9734d769d97470ce6fac0594dd007804d33432James Dong throw new RuntimeException("failure code: " + retcode); 6657a9734d769d97470ce6fac0594dd007804d33432James Dong } 66620cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania } 66720cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania 66820cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania /** 669cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * Sets the {@link SurfaceHolder} to use for displaying the video 67091784c996f95483e3041169215c0d6635e27ffccGloria Wang * portion of the media. 67132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 6720de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg * Either a surface holder or surface must be set if a display or video sink 673b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * is needed. Not calling this method or {@link #setSurface(Surface)} 674cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten * when playing back a video will result in only the audio track being played. 67591784c996f95483e3041169215c0d6635e27ffccGloria Wang * A null surface holder or surface will result in only the audio track being 67691784c996f95483e3041169215c0d6635e27ffccGloria Wang * played. 6775c2faf3dc310b100707eb9e32e1e5ae8ceffd0c6Glenn Kasten * 6785c2faf3dc310b100707eb9e32e1e5ae8ceffd0c6Glenn Kasten * @param sh the SurfaceHolder to use for video display 679cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten */ 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDisplay(SurfaceHolder sh) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSurfaceHolder = sh; 6821ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg Surface surface; 6838b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks if (sh != null) { 6841ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg surface = sh.getSurface(); 6858b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks } else { 6861ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg surface = null; 6878b0b174198793cabb2b3fcc015f9bfdc9d5082b5Dave Sparks } 6881ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg _setVideoSurface(surface); 689cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten updateSurfaceScreenOn(); 690cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten } 691cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten 692cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten /** 6930de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg * Sets the {@link Surface} to be used as the sink for the video portion of 694b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * the media. This is similar to {@link #setDisplay(SurfaceHolder)}, but 695b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * does not support {@link #setScreenOnWhilePlaying(boolean)}. Setting a 696b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * Surface will un-set any Surface or SurfaceHolder that was previously set. 69791784c996f95483e3041169215c0d6635e27ffccGloria Wang * A null surface will result in only the audio track being played. 6980de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg * 699b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps 700b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * returned from {@link SurfaceTexture#getTimestamp()} will have an 701b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * unspecified zero point. These timestamps cannot be directly compared 702b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * between different media sources, different instances of the same media 703b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * source, or multiple runs of the same program. The timestamp is normally 704b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * monotonically increasing and is unaffected by time-of-day adjustments, 705b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * but it is reset when the position is set. 7060de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg * 707b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * @param surface The {@link Surface} to be used for the video portion of 708b283dc64bc97f53804108cebf5b904eb4fb77155Jamie Gennis * the media. 7090de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg */ 7100de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg public void setSurface(Surface surface) { 7111ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg if (mScreenOnWhilePlaying && surface != null) { 7120de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface"); 7130de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg } 7140de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg mSurfaceHolder = null; 7151ee60119c4fa51ebfa781cf5fdc33f192e8551b8Ted Bonkenburg _setVideoSurface(surface); 7160de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg updateSurfaceScreenOn(); 7170de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg } 7180de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg 719454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong /* Do not change these video scaling mode values below without updating 720454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * their counterparts in system/window.h! Please do not forget to update 721454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * {@link #isVideoScalingModeSupported} when new video scaling modes 722454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * are added. 723454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong */ 724454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong /** 725454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * Specifies a video scaling mode. The content is stretched to the 726454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * surface rendering area. When the surface has the same aspect ratio 727454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * as the content, the aspect ratio of the content is maintained; 728454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * otherwise, the aspect ratio of the content is not maintained when video 729a45746efadd11bb7dfab026fb3c81a25fae74ca4Jeff Smith * is being rendered. Unlike {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}, 730454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * there is no content cropping with this video scaling mode. 731454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong */ 732454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; 733454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong 734454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong /** 735454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * Specifies a video scaling mode. The content is scaled, maintaining 736454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * its aspect ratio. The whole surface area is always used. When the 737454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * aspect ratio of the content is the same as the surface, no content 738454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * is cropped; otherwise, content is cropped to fit the surface. 739454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong */ 740454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; 741454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong /** 742454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * Sets video scaling mode. To make the target video scaling mode 743454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * effective during playback, this method must be called after 744454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * data source is set. If not called, the default video 745454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}. 746454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * 747454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <p> The supported video scaling modes are: 748454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <ul> 749454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT} 750454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING} 751454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * </ul> 752454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * 753454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * @param mode target video scaling mode. Most be one of the supported 754454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * video scaling modes; otherwise, IllegalArgumentException will be thrown. 755454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * 756454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT 757454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING 758454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong */ 759454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong public void setVideoScalingMode(int mode) { 76079a9cd40f5ebb2453cb982bc17d9797a1cbdf8d8Bryan Mawhinney if (!isVideoScalingModeSupported(mode)) { 761454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong final String msg = "Scaling mode " + mode + " is not supported"; 762454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong throw new IllegalArgumentException(msg); 763454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong } 764454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong Parcel request = Parcel.obtain(); 765454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong Parcel reply = Parcel.obtain(); 766be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang try { 767be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInterfaceToken(IMEDIA_PLAYER); 768be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE); 769c3a5cf9aab3d409445accb2a93c09e6b4140d196Bryan Mawhinney request.writeInt(mode); 770be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang invoke(request, reply); 771be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } finally { 772be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.recycle(); 773be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang reply.recycle(); 774be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } 775454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong } 776454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method to create a MediaPlayer for a given Uri. 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On success, {@link #prepare()} will already have been called and must not be called again. 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When done with the MediaPlayer, you should call {@link #release()}, 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to free the resources. If not released, too many MediaPlayer instances will 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result in an exception.</p> 78332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 78432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * @param context the Context to use 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the Uri from which to get the datasource 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a MediaPlayer object, or null if creation failed 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static MediaPlayer create(Context context, Uri uri) { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return create (context, uri, null); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 79132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method to create a MediaPlayer for a given Uri. 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On success, {@link #prepare()} will already have been called and must not be called again. 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When done with the MediaPlayer, you should call {@link #release()}, 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to free the resources. If not released, too many MediaPlayer instances will 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result in an exception.</p> 79832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 79932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * @param context the Context to use 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the Uri from which to get the datasource 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param holder the SurfaceHolder to use for displaying the video 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a MediaPlayer object, or null if creation failed 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) { 80532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaPlayer mp = new MediaPlayer(); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.setDataSource(context, uri); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (holder != null) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.setDisplay(holder); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.prepare(); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mp; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException ex) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException ex) { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException ex) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 828cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten // Note no convenience method to create a MediaPlayer with SurfaceTexture sink. 829cc562a3576a6a8096626387472e05e8bee03352aGlenn Kasten 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method to create a MediaPlayer for a given resource id. 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On success, {@link #prepare()} will already have been called and must not be called again. 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When done with the MediaPlayer, you should call {@link #release()}, 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to free the resources. If not released, too many MediaPlayer instances will 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result in an exception.</p> 83632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 83732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * @param context the Context to use 83832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * @param resid the raw resource id (<var>R.raw.<something></var>) for 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the resource to use as the datasource 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a MediaPlayer object, or null if creation failed 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static MediaPlayer create(Context context, int resid) { 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) return null; 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaPlayer mp = new MediaPlayer(); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.prepare(); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mp; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException ex) { 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException ex) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException ex) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "create failed:", ex); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 86432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the data source as a content Uri. 86732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the Context to use when resolving the Uri 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the Content URI of the data you want to play 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDataSource(Context context, Uri uri) 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { 874256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber setDataSource(context, uri, null); 875256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber } 876256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber 877256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber /** 878256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * Sets the data source as a content Uri. 879256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * 880256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @param context the Context to use when resolving the Uri 881256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @param uri the Content URI of the data you want to play 882256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @param headers the headers to be sent together with the request for the data 883256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @throws IllegalStateException if it is called in an invalid state 884256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber */ 885256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber public void setDataSource(Context context, Uri uri, Map<String, String> headers) 886256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { 887d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber disableProxyListener(); 88832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(scheme == null || scheme.equals("file")) { 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDataSource(uri.getPath()); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = null; 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = context.getContentResolver(); 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd = resolver.openAssetFileDescriptor(uri, "r"); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd == null) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: using getDeclaredLength so that our behavior is the same 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // as previous versions when the content provider is returning 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a full file. 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd.getDeclaredLength() < 0) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDataSource(fd.getFileDescriptor()); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength()); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException ex) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException ex) { 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd != null) { 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.close(); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 918fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke 919a2df60598ac0158468ce242498b7bd3cb9383e13Marco Nelissen Log.d(TAG, "Couldn't open file on client side, trying server side"); 920d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 921256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber setDataSource(uri.toString(), headers); 922d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 923d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (scheme.equalsIgnoreCase("http") 924d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber || scheme.equalsIgnoreCase("https")) { 925d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber setupProxyListener(context); 926d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the data source (file-path or http/rtsp URL) to use. 93132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param path the path of the file, or the http/rtsp URL of the stream you want to play 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 93455d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * 93555d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * <p>When <code>path</code> refers to a local file, the file may actually be opened by a 93655d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * process other than the calling application. This implies that the pathname 93755d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * should be an absolute path (as any other process runs with unspecified current working 93855d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * directory), and that the pathname should reference a world-readable file. 93955d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * As an alternative, the application could first open the file for reading, 94055d1eea69451ee246a41e12a14be42878773e3cbGlenn Kasten * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}. 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 942e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong public void setDataSource(String path) 943e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { 944e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong setDataSource(path, null, null); 945e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 948256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * Sets the data source (file-path or http/rtsp URL) to use. 949256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * 950256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @param path the path of the file, or the http/rtsp URL of the stream you want to play 951256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @param headers the headers associated with the http request for the stream you want to play 952256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @throws IllegalStateException if it is called in an invalid state 953256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber * @hide pending API council 954256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber */ 95517524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong public void setDataSource(String path, Map<String, String> headers) 956fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke throws IOException, IllegalArgumentException, SecurityException, IllegalStateException 95717524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong { 958e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber String[] keys = null; 959e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber String[] values = null; 960e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber 961e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber if (headers != null) { 962e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber keys = new String[headers.size()]; 963e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber values = new String[headers.size()]; 964e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber 965e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber int i = 0; 966e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber for (Map.Entry<String, String> entry: headers.entrySet()) { 967e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber keys[i] = entry.getKey(); 968e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber values[i] = entry.getValue(); 969e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber ++i; 970e4e7b48e33fbdfc00f184c18c50e9f3d6335c5acAndreas Huber } 97117524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong } 972e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong setDataSource(path, keys, values); 973e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong } 974e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong 975e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong private void setDataSource(String path, String[] keys, String[] values) 976e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong throws IOException, IllegalArgumentException, SecurityException, IllegalStateException { 977d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber disableProxyListener(); 978d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 979c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey final Uri uri = Uri.parse(path); 980c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey if ("file".equals(uri.getScheme())) { 981c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey path = uri.getPath(); 982c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey } 983c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey 984c058a380de5a7eb5427cef295f1c259c507e25bdJeff Sharkey final File file = new File(path); 985e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong if (file.exists()) { 986e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong FileInputStream is = new FileInputStream(file); 987e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong FileDescriptor fd = is.getFD(); 988e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong setDataSource(fd); 989e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong is.close(); 990e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong } else { 991e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong _setDataSource(path, keys, values); 992e00b6f3a57d4b480ce674468de93555269bbd71aJames Dong } 99317524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong } 99417524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong 99517524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong private native void _setDataSource( 99617524dc0d296146c8ffb3f692dc8ab05fee5b1e0James Dong String path, String[] keys, String[] values) 997fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke throws IOException, IllegalArgumentException, SecurityException, IllegalStateException; 998256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber 999256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber /** 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the data source (FileDescriptor) to use. It is the caller's responsibility 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to close the file descriptor. It is safe to do so as soon as this call returns. 100232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd the FileDescriptor for the file you want to play 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 100632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania public void setDataSource(FileDescriptor fd) 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, IllegalArgumentException, IllegalStateException { 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // intentionally less than LONG_MAX 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setDataSource(fd, 0, 0x7ffffffffffffffL); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10136ab180aa65d2b4f155518af0ac7bb2777f9ce61fKenny Root * Sets the data source (FileDescriptor) to use. The FileDescriptor must be 10146ab180aa65d2b4f155518af0ac7bb2777f9ce61fKenny Root * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to close the file descriptor. It is safe to do so as soon as this call returns. 101632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fd the FileDescriptor for the file you want to play 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param offset the offset into the file where the data to be played starts, in bytes 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param length the length in bytes of the data to be played 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1022d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber public void setDataSource(FileDescriptor fd, long offset, long length) 1023d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber throws IOException, IllegalArgumentException, IllegalStateException { 1024d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber disableProxyListener(); 1025d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber _setDataSource(fd, offset, length); 1026d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 1027d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 1028d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private native void _setDataSource(FileDescriptor fd, long offset, long length) 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, IllegalArgumentException, IllegalStateException; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Prepares the player for playback, synchronously. 103332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * After setting the datasource and the display surface, you need to either 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call prepare() or prepareAsync(). For files, it is OK to call prepare(), 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which blocks until MediaPlayer is ready for playback. 103732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void prepare() throws IOException, IllegalStateException; 104132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Prepares the player for playback, asynchronously. 104432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * After setting the datasource and the display surface, you need to either 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call prepare() or prepareAsync(). For streams, you should call prepareAsync(), 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which returns immediately, rather than blocking until enough data has been 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * buffered. 104932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void prepareAsync() throws IllegalStateException; 105332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Starts or resumes playback. If playback had previously been paused, 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * playback will continue from where it was paused. If playback had 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * been stopped, or never started before, playback will start at the 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * beginning. 105932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if it is called in an invalid state 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void start() throws IllegalStateException { 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(true); 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _start(); 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void _start() throws IllegalStateException; 106832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 107032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * Stops playback after playback has been stopped or paused. 107132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if the internal player engine has not been 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initialized. 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stop() throws IllegalStateException { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _stop(); 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void _stop() throws IllegalStateException; 108132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Pauses playback. Call start() to resume. 108432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if the internal player engine has not been 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initialized. 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void pause() throws IllegalStateException { 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _pause(); 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void _pause() throws IllegalStateException; 109432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the low-level power management behavior for this MediaPlayer. This 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can be used when the MediaPlayer is not playing through a SurfaceHolder 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * set with {@link #setDisplay(SurfaceHolder)} and thus can use the 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * high-level {@link #setScreenOnWhilePlaying(boolean)} feature. 110032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This function has the MediaPlayer access the low-level power manager 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * service to control the device's power usage while playing is occurring. 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The parameter is a combination of {@link android.os.PowerManager} wake flags. 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK} 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * permission. 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, no attempt is made to keep the device awake during playback. 110732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the Context to use 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode the power/wake mode to set 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.os.PowerManager 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWakeMode(Context context, int mode) { 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean washeld = false; 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWakeLock != null) { 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWakeLock.isHeld()) { 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project washeld = true; 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = null; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = pm.newWakeLock(mode|PowerManager.ON_AFTER_RELEASE, MediaPlayer.class.getName()); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.setReferenceCounted(false); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (washeld) { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 112932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether we should use the attached SurfaceHolder to keep the 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen on while video playback is occurring. This is the preferred 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method over {@link #setWakeMode} where possible, since it doesn't 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * require that the application have permission for low-level wake lock 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * access. 113632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param screenOn Supply true to keep the screen on, false to allow it 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to turn off. 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setScreenOnWhilePlaying(boolean screenOn) { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mScreenOnWhilePlaying != screenOn) { 11420de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg if (screenOn && mSurfaceHolder == null) { 11430de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder"); 1144817c161ef27b6087c496755768d65fcb4f78f04cGlenn Kasten } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenOnWhilePlaying = screenOn; 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateSurfaceScreenOn(); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void stayAwake(boolean awake) { 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mWakeLock != null) { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (awake && !mWakeLock.isHeld()) { 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.acquire(); 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!awake && mWakeLock.isHeld()) { 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock.release(); 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStayAwake = awake; 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateSurfaceScreenOn(); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 116132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateSurfaceScreenOn() { 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSurfaceHolder != null) { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 116732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the width of the video. 117032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the width of the video, or 0 if there is no video, 1172ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * no display surface was set, or the width has not been determined 1173ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * yet. The OnVideoSizeChangedListener can be registered via 1174ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)} 1175ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * to provide a notification when the width is available. 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int getVideoWidth(); 117832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the height of the video. 118132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height of the video, or 0 if there is no video, 1183ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * no display surface was set, or the height has not been determined 1184ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * yet. The OnVideoSizeChangedListener can be registered via 1185ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)} 1186ea5f767246ad201a9e2bba0d657404e002cd7c70Jean-Baptiste Queru * to provide a notification when the height is available. 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int getVideoHeight(); 118932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Checks whether the MediaPlayer is playing. 119232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if currently playing, false otherwise 1194099fd80f984b8493de58bdda8ea05563261b0af2Scott Main * @throws IllegalStateException if the internal player engine has not been 1195099fd80f984b8493de58bdda8ea05563261b0af2Scott Main * initialized or has been released. 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native boolean isPlaying(); 119832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Seeks to specified time position. 120132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param msec the offset in milliseconds from the start to seek to 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if the internal player engine has not been 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initialized 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void seekTo(int msec) throws IllegalStateException; 120732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the current playback position. 121032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the current position in milliseconds 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int getCurrentPosition(); 121432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the duration of the file. 121732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 12187cd281c332e81c93fde44d1a394b04843bebd723Andreas Huber * @return the duration in milliseconds, if no duration is available 12197cd281c332e81c93fde44d1a394b04843bebd723Andreas Huber * (for example, if streaming live content), -1 is returned. 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native int getDuration(); 122232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12249193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Gets the media metadata. 12259193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12269193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @param update_only controls whether the full set of available 12279193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * metadata is returned or just the set that changed since the 12289193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * last call. See {@see #METADATA_UPDATE_ONLY} and {@see 12299193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * #METADATA_ALL}. 12309193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12319193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @param apply_filter if true only metadata that matches the 12329193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * filter is returned. See {@see #APPLY_METADATA_FILTER} and {@see 12339193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * #BYPASS_METADATA_FILTER}. 12349193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12359193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @return The metadata, possibly empty. null if an error occured. 12369193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 12379193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * {@hide} 12389193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 12399193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public Metadata getMetadata(final boolean update_only, 12409193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania final boolean apply_filter) { 12415d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania Parcel reply = Parcel.obtain(); 12425d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania Metadata data = new Metadata(); 12435d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 12445d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania if (!native_getMetadata(update_only, apply_filter, reply)) { 12455d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania reply.recycle(); 12465d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania return null; 12475d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania } 12485d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 12495d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania // Metadata takes over the parcel, don't recycle it unless 12505d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania // there is an error. 12515d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania if (!data.parse(reply)) { 12525d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania reply.recycle(); 12535d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania return null; 12545d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania } 12555d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania return data; 12569193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 12579193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 12589193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 12599193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Set a filter for the metadata update notification and update 12609193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * retrieval. The caller provides 2 set of metadata keys, allowed 1261b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * and blocked. The blocked set always takes precedence over the 1262b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * allowed one. 12639193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as 1264b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * shorthands to allow/block all or no metadata. 12659193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12669193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * By default, there is no filter set. 12679193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12689193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @param allow Is the set of metadata the client is interested 1269b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * in receiving new notifications for. 1270b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * @param block Is the set of metadata the client is not interested 1271b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * in receiving new notifications for. 12729193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @return The call status code. 12739193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * 12749193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania // FIXME: unhide. 12759193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * {@hide} 12769193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 1277b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) { 1278b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // Do our serialization manually instead of calling 1279b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // Parcel.writeArray since the sets are made of the same type 1280b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // we avoid paying the price of calling writeValue (used by 1281b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // writeArray) which burns an extra int per element to encode 1282b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // the type. 1283b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania Parcel request = newRequest(); 1284b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania 1285b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // The parcel starts already with an interface token. There 1286b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // are 2 filters. Each one starts with a 4bytes number to 1287b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // store the len followed by a number of int (4 bytes as well) 1288b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania // representing the metadata type. 1289b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania int capacity = request.dataSize() + 4 * (1 + allow.size() + 1 + block.size()); 1290b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania 1291b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania if (request.dataCapacity() < capacity) { 1292b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania request.setDataCapacity(capacity); 1293b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania } 1294b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania 1295b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania request.writeInt(allow.size()); 1296b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania for(Integer t: allow) { 1297b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania request.writeInt(t); 1298b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania } 1299b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania request.writeInt(block.size()); 1300b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania for(Integer t: block) { 1301b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania request.writeInt(t); 1302b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania } 1303b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania return native_setMetadataFilter(request); 13049193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania } 13059193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 13069193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** 130784b832054552e00257bb04997143ca33d6d100beMarco Nelissen * Set the MediaPlayer to start when this MediaPlayer finishes playback 130884b832054552e00257bb04997143ca33d6d100beMarco Nelissen * (i.e. reaches the end of the stream). 130984b832054552e00257bb04997143ca33d6d100beMarco Nelissen * The media framework will attempt to transition from this player to 131084b832054552e00257bb04997143ca33d6d100beMarco Nelissen * the next as seamlessly as possible. The next player can be set at 131184b832054552e00257bb04997143ca33d6d100beMarco Nelissen * any time before completion. The next player must be prepared by the 131284b832054552e00257bb04997143ca33d6d100beMarco Nelissen * app, and the application should not call start() on it. 131384b832054552e00257bb04997143ca33d6d100beMarco Nelissen * The next MediaPlayer must be different from 'this'. An exception 131484b832054552e00257bb04997143ca33d6d100beMarco Nelissen * will be thrown if next == this. 131584b832054552e00257bb04997143ca33d6d100beMarco Nelissen * The application may call setNextMediaPlayer(null) to indicate no 131684b832054552e00257bb04997143ca33d6d100beMarco Nelissen * next player should be started at the end of playback. 131784b832054552e00257bb04997143ca33d6d100beMarco Nelissen * If the current player is looping, it will keep looping and the next 131884b832054552e00257bb04997143ca33d6d100beMarco Nelissen * player will not be started. 131984b832054552e00257bb04997143ca33d6d100beMarco Nelissen * 132084b832054552e00257bb04997143ca33d6d100beMarco Nelissen * @param next the player to start after this one completes playback. 132184b832054552e00257bb04997143ca33d6d100beMarco Nelissen * 132284b832054552e00257bb04997143ca33d6d100beMarco Nelissen */ 132384b832054552e00257bb04997143ca33d6d100beMarco Nelissen public native void setNextMediaPlayer(MediaPlayer next); 132484b832054552e00257bb04997143ca33d6d100beMarco Nelissen 132584b832054552e00257bb04997143ca33d6d100beMarco Nelissen /** 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Releases resources associated with this MediaPlayer object. 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It is considered good practice to call this method when you're 132889ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * done using the MediaPlayer. In particular, whenever an Activity 132989ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * of an application is paused (its onPause() method is called), 133089ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * or stopped (its onStop() method is called), this method should be 133189ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * invoked to release the MediaPlayer object, unless the application 133289ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * has a special need to keep the object around. In addition to 133389ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * unnecessary resources (such as memory and instances of codecs) 133489ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * being held, failure to call this method immediately if a 133589ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * MediaPlayer object is no longer needed may also lead to 133689ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * continuous battery consumption for mobile devices, and playback 133789ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * failure for other applications if no multiple instances of the 133889ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * same codec are supported on a device. Even if multiple instances 133989ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * of the same codec are supported, some performance degradation 134089ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * may be expected when unnecessary multiple instances are used 134189ca6983eb2be21848f5ac884a2c118f152c83e6James Dong * at the same time. 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void release() { 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateSurfaceScreenOn(); 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreparedListener = null; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnBufferingUpdateListener = null; 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCompletionListener = null; 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnSeekCompleteListener = null; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnErrorListener = null; 1351c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mOnInfoListener = null; 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnVideoSizeChangedListener = null; 1353162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang mOnTimedTextListener = null; 1354a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mTimeProvider != null) { 1355a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mTimeProvider.close(); 1356a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mTimeProvider = null; 1357a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 135883ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang mOnSubtitleDataListener = null; 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _release(); 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void _release(); 136332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Resets the MediaPlayer to its uninitialized state. After calling 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this method, you will have to initialize it again by setting the 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data source and calling prepare(). 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void reset() { 1370484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSelectedSubtitleTrackIndex = -1; 1371484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar synchronized(mOpenSubtitleSources) { 1372484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar for (final InputStream is: mOpenSubtitleSources) { 1373484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar try { 1374484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar is.close(); 1375484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } catch (IOException e) { 1376484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1377484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1378484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOpenSubtitleSources.clear(); 1379484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1380484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOutOfBandSubtitleTracks.clear(); 1381484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mInbandSubtitleTracks = new SubtitleTrack[0]; 1382484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (mSubtitleController != null) { 1383484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSubtitleController.reset(); 1384484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1385a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mTimeProvider != null) { 1386a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mTimeProvider.close(); 1387a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mTimeProvider = null; 1388a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 1389484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _reset(); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure none of the listeners get called anymore 1393a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mEventHandler != null) { 1394a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mEventHandler.removeCallbacksAndMessages(null); 1395a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 1396d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 1397d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber disableProxyListener(); 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 139932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void _reset(); 140132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the audio stream type for this MediaPlayer. See {@link AudioManager} 14049d96354d7055cd165d7d5625990f810f46339e52James Dong * for a list of stream types. Must call this method before prepare() or 14059d96354d7055cd165d7d5625990f810f46339e52James Dong * prepareAsync() in order for the target stream type to become effective 14069d96354d7055cd165d7d5625990f810f46339e52James Dong * thereafter. 140732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param streamtype the audio stream type 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.media.AudioManager 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void setAudioStreamType(int streamtype); 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the player to be looping or non-looping. 141532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param looping whether to loop or not 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void setLooping(boolean looping); 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Checks whether the MediaPlayer is looping or non-looping. 142232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the MediaPlayer is currently looping, false otherwise 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native boolean isLooping(); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 142832f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * Sets the volume on this player. 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This API is recommended for balancing the output of audio streams 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * within an application. Unless you are writing an application to 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * control user settings, this API should be used in preference to 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of 1433068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0. 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * UI controls should be scaled logarithmically. 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param leftVolume left volume scalar 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rightVolume right volume scalar 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1439068225de0197df07a0247b2877666ea91c22c992Glenn Kasten /* 1440068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide. 1441068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * The single parameter form below is preferred if the channel volumes don't need 1442068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * to be set independently. 1443068225de0197df07a0247b2877666ea91c22c992Glenn Kasten */ 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native void setVolume(float leftVolume, float rightVolume); 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1447068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * Similar, excepts sets volume of all channels to same value. 1448068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * @hide 1449068225de0197df07a0247b2877666ea91c22c992Glenn Kasten */ 1450068225de0197df07a0247b2877666ea91c22c992Glenn Kasten public void setVolume(float volume) { 1451068225de0197df07a0247b2877666ea91c22c992Glenn Kasten setVolume(volume, volume); 1452068225de0197df07a0247b2877666ea91c22c992Glenn Kasten } 1453068225de0197df07a0247b2877666ea91c22c992Glenn Kasten 1454068225de0197df07a0247b2877666ea91c22c992Glenn Kasten /** 1455619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Sets the audio session ID. 1456619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * 145717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * @param sessionId the audio session ID. 1458619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * The audio session ID is a system wide unique identifier for the audio stream played by 1459619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * this MediaPlayer instance. 1460619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * The primary use of the audio session ID is to associate audio effects to a particular 1461619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * instance of MediaPlayer: if an audio session ID is provided when creating an audio effect, 1462619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * this effect will be applied only to the audio content of media players within the same 1463619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * audio session and not to the output mix. 1464619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * When created, a MediaPlayer instance automatically generates its own audio session ID. 1465619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * However, it is possible to force this player to be part of an already existing audio session 1466619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * by calling this method. 1467619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * This method must be called before one of the overloaded <code> setDataSource </code> methods. 1468619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @throws IllegalStateException if it is called in an invalid state 1469619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent */ 1470619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent public native void setAudioSessionId(int sessionId) throws IllegalArgumentException, IllegalStateException; 1471619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 1472619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent /** 1473619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Returns the audio session ID. 1474619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * 147517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * @return the audio session ID. {@see #setAudioSessionId(int)} 1476619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer was contructed. 1477619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent */ 1478619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent public native int getAudioSessionId(); 1479619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 1480619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent /** 14817070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation 14827070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * effect which can be applied on any sound source that directs a certain amount of its 14837070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * energy to this effect. This amount is defined by setAuxEffectSendLevel(). 14847070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * {@see #setAuxEffectSendLevel(float)}. 14851a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>After creating an auxiliary effect (e.g. 14861a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with 14871a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method 14881a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * to attach the player to the effect. 14897070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * <p>To detach the effect from the player, call this method with a null effect id. 14907070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * <p>This method must be called after one of the overloaded <code> setDataSource </code> 14917070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * methods. 14927070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * @param effectId system wide unique id of the effect to attach 14937070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent */ 14947070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent public native void attachAuxEffect(int effectId); 14957070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent 1496d01ec6eab019e46398975202e9e4a198a603ad99Gloria Wang 1497d01ec6eab019e46398975202e9e4a198a603ad99Gloria Wang /** 14987070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * Sets the send level of the player to the attached auxiliary effect 14997070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0. 15007070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * <p>By default the send level is 0, so even if an effect is attached to the player 15017070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * this method must be called for the effect to be applied. 15027070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * <p>Note that the passed level value is a raw scalar. UI controls should be scaled 15037070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB, 15047070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * so an appropriate conversion from linear UI input x to level is: 15057070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * x == 0 -> level = 0 15067070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * 0 < x <= R -> level = 10^(72*(x-R)/20/R) 15077070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent * @param level send level scalar 15087070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent */ 15097070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent public native void setAuxEffectSendLevel(float level); 15107070b36549d511d6627538c73dfbab23fbae5b43Eric Laurent 151141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* 151220cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * @param request Parcel destinated to the media player. The 151320cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * Interface token must be set to the IMediaPlayer 151420cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * one to be routed correctly through the system. 15155d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * @param reply[out] Parcel that will contain the reply. 151620cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania * @return The status code. 151720cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania */ 151820cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania private native final int native_invoke(Parcel request, Parcel reply); 151920cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania 15205d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 152141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* 15225d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * @param update_only If true fetch only the set of metadata that have 15235d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * changed since the last invocation of getMetadata. 15245d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * The set is built using the unfiltered 15255d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * notifications the native player sent to the 15265d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * MediaPlayerService during that period of 15275d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * time. If false, all the metadatas are considered. 15285d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * @param apply_filter If true, once the metadata set has been built based on 15295d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * the value update_only, the current filter is applied. 15305d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * @param reply[out] On return contains the serialized 15315d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * metadata. Valid only if the call was successful. 15325d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania * @return The status code. 15335d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania */ 15345d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania private native final boolean native_getMetadata(boolean update_only, 15355d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania boolean apply_filter, 15365d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania Parcel reply); 15375d55c7119820ee9bb06fc072e416fe98ba77cd28Nicolas Catania 153841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* 1539b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * @param request Parcel with the 2 serialized lists of allowed 1540b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * metadata types followed by the one to be 1541b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * dropped. Each list starts with an integer 1542b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * indicating the number of metadata type elements. 1543b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania * @return The status code. 1544b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania */ 1545b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania private native final int native_setMetadataFilter(Parcel request); 1546b2c693919be966f179080a9ec70a7a82dbf57627Nicolas Catania 15474935d05eaa306cef88cf0ab13eca386f270409ecMarco Nelissen private static native final void native_init(); 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_setup(Object mediaplayer_this); 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_finalize(); 155020cb94eeb5b9672573fc86bf51e09bd66a774581Nicolas Catania 1551d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang /** 155241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Class for MediaPlayer to return each audio/video/subtitle track's metadata. 155341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 15547a9734d769d97470ce6fac0594dd007804d33432James Dong * @see android.media.MediaPlayer#getTrackInfo 155541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 155641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang static public class TrackInfo implements Parcelable { 155741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 155841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Gets the track type. 155941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @return TrackType which indicates if the track is video, audio, timed text. 156041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 156141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public int getTrackType() { 156241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return mTrackType; 156341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 156441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 156541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 156641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Gets the language code of the track. 156741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @return a language code in either way of ISO-639-1 or ISO-639-2. 156841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * When the language is unknown or could not be determined, 156941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * ISO-639-2 language code, "und", is returned. 157041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 157141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public String getLanguage() { 15721c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar String language = mFormat.getString(MediaFormat.KEY_LANGUAGE); 15731c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar return language == null ? "und" : language; 15741c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar } 15751c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar 15761c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar /** 15771c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar * Gets the {@link MediaFormat} of the track. If the format is 15781c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar * unknown or could not be determined, null is returned. 15791c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar */ 15801c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar public MediaFormat getFormat() { 1581f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT 1582f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang || mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) { 15831c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar return mFormat; 15841c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar } 15851c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar return null; 158641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 158741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 158841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; 158941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public static final int MEDIA_TRACK_TYPE_VIDEO = 1; 159041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public static final int MEDIA_TRACK_TYPE_AUDIO = 2; 159141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3; 159283ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang /** @hide */ 159383ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; 159441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 159541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang final int mTrackType; 15961c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar final MediaFormat mFormat; 159741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 159841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang TrackInfo(Parcel in) { 159941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang mTrackType = in.readInt(); 16001c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar // TODO: parcel in the full MediaFormat 16011c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar String language = in.readString(); 16021c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar 16031c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT) { 16041c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar mFormat = MediaFormat.createSubtitleFormat( 16051c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar MEDIA_MIMETYPE_TEXT_SUBRIP, language); 1606f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang } else if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) { 1607f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang mFormat = MediaFormat.createSubtitleFormat( 1608f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang MEDIA_MIMETYPE_TEXT_VTT, language); 1609d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mFormat.setInteger(MediaFormat.KEY_IS_AUTOSELECT, in.readInt()); 1610d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mFormat.setInteger(MediaFormat.KEY_IS_DEFAULT, in.readInt()); 1611d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mFormat.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.readInt()); 16121c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar } else { 16131c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar mFormat = new MediaFormat(); 16141c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar mFormat.setString(MediaFormat.KEY_LANGUAGE, language); 16151c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar } 161641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 161741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 1618484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar /** @hide */ 1619484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar TrackInfo(int type, MediaFormat format) { 1620484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mTrackType = type; 1621484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mFormat = format; 1622484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1623484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 16247a9734d769d97470ce6fac0594dd007804d33432James Dong /** 16257a9734d769d97470ce6fac0594dd007804d33432James Dong * {@inheritDoc} 162641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 162741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang @Override 162841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public int describeContents() { 162941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return 0; 163041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 163141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 16327a9734d769d97470ce6fac0594dd007804d33432James Dong /** 16337a9734d769d97470ce6fac0594dd007804d33432James Dong * {@inheritDoc} 163441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 163541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang @Override 163641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public void writeToParcel(Parcel dest, int flags) { 163741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang dest.writeInt(mTrackType); 16381c56a67dbbade39b1d88738a49fd31b4f97df0abLajos Molnar dest.writeString(getLanguage()); 1639f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang 1640f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) { 1641d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_AUTOSELECT)); 1642d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_DEFAULT)); 1643d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE)); 1644f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang } 164541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 164641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 164741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 164841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Used to read a TrackInfo from a Parcel. 164941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 165041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang static final Parcelable.Creator<TrackInfo> CREATOR 165141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang = new Parcelable.Creator<TrackInfo>() { 165241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang @Override 165341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public TrackInfo createFromParcel(Parcel in) { 165441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return new TrackInfo(in); 165541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 165641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 165741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang @Override 165841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public TrackInfo[] newArray(int size) { 165941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return new TrackInfo[size]; 166041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 166141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang }; 166241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 166341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang }; 166441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 166541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 166641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Returns an array of track information. 166741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 1668831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @return Array of track info. The total number of tracks is the array length. 16697a9734d769d97470ce6fac0594dd007804d33432James Dong * Must be called again if an external timed text source has been added after any of the 16707a9734d769d97470ce6fac0594dd007804d33432James Dong * addTimedTextSource methods are called. 16717a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if it is called in an invalid state. 167241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 16737a9734d769d97470ce6fac0594dd007804d33432James Dong public TrackInfo[] getTrackInfo() throws IllegalStateException { 1674484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar TrackInfo trackInfo[] = getInbandTrackInfo(); 1675484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // add out-of-band tracks 1676484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()]; 1677484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length); 1678484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar int i = trackInfo.length; 1679484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar for (SubtitleTrack track: mOutOfBandSubtitleTracks) { 1680484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar allTrackInfo[i] = new TrackInfo(TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE, track.getFormat()); 1681484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar ++i; 1682484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1683484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return allTrackInfo; 1684484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1685484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1686484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private TrackInfo[] getInbandTrackInfo() throws IllegalStateException { 168741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel request = Parcel.obtain(); 168841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel reply = Parcel.obtain(); 1689be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang try { 1690be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInterfaceToken(IMEDIA_PLAYER); 1691be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInt(INVOKE_ID_GET_TRACK_INFO); 1692be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang invoke(request, reply); 1693be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR); 1694be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang return trackInfo; 1695be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } finally { 1696be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.recycle(); 1697be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang reply.recycle(); 1698be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } 169941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 170041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 1701831f0a90cad923ec6b00c5c598ac4356e5849431James Dong /* Do not change these values without updating their counterparts 1702831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp! 1703831f0a90cad923ec6b00c5c598ac4356e5849431James Dong */ 1704831f0a90cad923ec6b00c5c598ac4356e5849431James Dong /** 17057a9734d769d97470ce6fac0594dd007804d33432James Dong * MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs. 1706831f0a90cad923ec6b00c5c598ac4356e5849431James Dong */ 1707831f0a90cad923ec6b00c5c598ac4356e5849431James Dong public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip"; 1708831f0a90cad923ec6b00c5c598ac4356e5849431James Dong 1709f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang /** 1710f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang * MIME type for WebVTT subtitle data. 1711f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang * @hide 1712f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang */ 1713f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang public static final String MEDIA_MIMETYPE_TEXT_VTT = "text/vtt"; 1714f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang 171541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* 171641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * A helper function to check if the mime type is supported by media framework. 171741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 1718831f0a90cad923ec6b00c5c598ac4356e5849431James Dong private static boolean availableMimeTypeForExternalSource(String mimeType) { 171941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (mimeType == MEDIA_MIMETYPE_TEXT_SUBRIP) { 172041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return true; 172141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 172241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return false; 172341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 172441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 1725484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private SubtitleController mSubtitleController; 1726484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1727484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar /** @hide */ 1728484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public void setSubtitleAnchor( 1729484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar SubtitleController controller, 1730484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar SubtitleController.Anchor anchor) { 1731484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // TODO: create SubtitleController in MediaPlayer 1732484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSubtitleController = controller; 1733484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSubtitleController.setAnchor(anchor); 1734484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1735484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1736484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private SubtitleTrack[] mInbandSubtitleTracks; 1737484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private int mSelectedSubtitleTrackIndex = -1; 1738484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private Vector<SubtitleTrack> mOutOfBandSubtitleTracks; 1739484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private Vector<InputStream> mOpenSubtitleSources; 1740484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1741484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private OnSubtitleDataListener mSubtitleDataListener = new OnSubtitleDataListener() { 1742484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar @Override 1743484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public void onSubtitleData(MediaPlayer mp, SubtitleData data) { 1744484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar int index = data.getTrackIndex(); 1745484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (index >= mInbandSubtitleTracks.length) { 1746484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return; 1747484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1748484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar SubtitleTrack track = mInbandSubtitleTracks[index]; 1749484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (track != null) { 1750484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar try { 1751484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar long runID = data.getStartTimeUs() + 1; 1752484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // TODO: move conversion into track 1753484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar track.onData(new String(data.getData(), "UTF-8"), true /* eos */, runID); 1754484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar track.setRunDiscardTimeMs( 1755484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar runID, 1756484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar (data.getStartTimeUs() + data.getDurationUs()) / 1000); 1757484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } catch (java.io.UnsupportedEncodingException e) { 1758484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Log.w(TAG, "subtitle data for track " + index + " is not UTF-8 encoded: " + e); 1759484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1760484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1761484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1762484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar }; 1763484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1764484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar /** @hide */ 1765484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar @Override 1766484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public void onSubtitleTrackSelected(SubtitleTrack track) { 1767484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (mSelectedSubtitleTrackIndex >= 0) { 1768d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar try { 1769d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, false); 1770d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } catch (IllegalStateException e) { 1771d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } 1772d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mSelectedSubtitleTrackIndex = -1; 1773484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1774484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar setOnSubtitleDataListener(null); 177529f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar if (track == null) { 177629f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar return; 177729f5183794efd58a3442aedcf829e3dbcd3fd867Lajos Molnar } 1778484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar for (int i = 0; i < mInbandSubtitleTracks.length; i++) { 1779484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (mInbandSubtitleTracks[i] == track) { 1780484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Log.v(TAG, "Selecting subtitle track " + i); 1781484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSelectedSubtitleTrackIndex = i; 1782d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar try { 1783d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, true); 1784d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } catch (IllegalStateException e) { 1785d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } 1786484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar setOnSubtitleDataListener(mSubtitleDataListener); 1787484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar break; 1788484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1789484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1790484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // no need to select out-of-band tracks 1791484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1792484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1793484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar /** @hide */ 1794484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public void addSubtitleSource(InputStream is, MediaFormat format) 1795484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar throws IllegalStateException 1796484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar { 1797484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar final InputStream fIs = is; 1798484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar final MediaFormat fFormat = format; 1799484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1800484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // Ensure all input streams are closed. It is also a handy 1801484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // way to implement timeouts in the future. 1802484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar synchronized(mOpenSubtitleSources) { 1803484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOpenSubtitleSources.add(is); 1804484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1805484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1806484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // process each subtitle in its own thread 1807484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar final HandlerThread thread = new HandlerThread("SubtitleReadThread", 1808484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE); 1809484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar thread.start(); 1810484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Handler handler = new Handler(thread.getLooper()); 1811484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar handler.post(new Runnable() { 1812484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private int addTrack() { 1813484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (fIs == null || mSubtitleController == null) { 1814484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return MEDIA_INFO_UNSUPPORTED_SUBTITLE; 1815484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1816484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1817484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar SubtitleTrack track = mSubtitleController.addTrack(fFormat); 1818484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (track == null) { 1819484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return MEDIA_INFO_UNSUPPORTED_SUBTITLE; 1820484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1821484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1822484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar // TODO: do the conversion in the subtitle track 1823484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Scanner scanner = new Scanner(fIs, "UTF-8"); 1824484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar String contents = scanner.useDelimiter("\\A").next(); 1825484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar synchronized(mOpenSubtitleSources) { 1826484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOpenSubtitleSources.remove(fIs); 1827484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1828484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar scanner.close(); 1829484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mOutOfBandSubtitleTracks.add(track); 1830484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar track.onData(contents, true /* eos */, ~0 /* runID: keep forever */); 1831484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return MEDIA_INFO_EXTERNAL_METADATA_UPDATE; 1832484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1833484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1834484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public void run() { 1835484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar int res = addTrack(); 1836484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (mEventHandler != null) { 1837484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null); 1838484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mEventHandler.sendMessage(m); 1839484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1840484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar thread.getLooper().quitSafely(); 1841484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1842484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar }); 1843484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1844484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1845484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar private void scanInternalSubtitleTracks() { 1846484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (mSubtitleController == null) { 1847484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar Log.e(TAG, "Should have subtitle controller already set"); 1848484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return; 1849484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1850484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 1851484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar TrackInfo[] tracks = getInbandTrackInfo(); 1852484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length]; 1853484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar for (int i=0; i < tracks.length; i++) { 1854484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) { 1855484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar if (i < mInbandSubtitleTracks.length) { 1856484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar inbandTracks[i] = mInbandSubtitleTracks[i]; 1857484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } else { 1858f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang SubtitleTrack track = mSubtitleController.addTrack( 1859f8ca13b7a09f6262f13f0301abed0ecde5175c9aChong Zhang tracks[i].getFormat()); 1860484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar inbandTracks[i] = track; 1861484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1862484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1863484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1864484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mInbandSubtitleTracks = inbandTracks; 1865484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar mSubtitleController.selectDefaultTrack(); 1866484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 1867484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 186841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* TODO: Limit the total number of external timed text source to a reasonable number. 186941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 187041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 18717a9734d769d97470ce6fac0594dd007804d33432James Dong * Adds an external timed text source file. 187241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 187341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Currently supported format is SubRip with the file extension .srt, case insensitive. 18747a9734d769d97470ce6fac0594dd007804d33432James Dong * Note that a single external timed text source may contain multiple tracks in it. 187541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * One can find the total number of available tracks using {@link #getTrackInfo()} to see what 187641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * additional tracks become available after this method call. 187741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 18787a9734d769d97470ce6fac0594dd007804d33432James Dong * @param path The file path of external timed text source file. 1879831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @param mimeType The mime type of the file. Must be one of the mime types listed above. 1880831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IOException if the file cannot be accessed or is corrupted. 1881831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IllegalArgumentException if the mimeType is not supported. 18827a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 188341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 18847a9734d769d97470ce6fac0594dd007804d33432James Dong public void addTimedTextSource(String path, String mimeType) 18857a9734d769d97470ce6fac0594dd007804d33432James Dong throws IOException, IllegalArgumentException, IllegalStateException { 188641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (!availableMimeTypeForExternalSource(mimeType)) { 18877a9734d769d97470ce6fac0594dd007804d33432James Dong final String msg = "Illegal mimeType for timed text source: " + mimeType; 1888c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong throw new IllegalArgumentException(msg); 188941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 189041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 1891c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong File file = new File(path); 1892c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong if (file.exists()) { 1893c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong FileInputStream is = new FileInputStream(file); 1894c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong FileDescriptor fd = is.getFD(); 18957a9734d769d97470ce6fac0594dd007804d33432James Dong addTimedTextSource(fd, mimeType); 1896c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong is.close(); 1897c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong } else { 1898c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong // We do not support the case where the path is not a file. 1899c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong throw new IOException(path); 1900c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong } 190141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 190241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 190341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 19047a9734d769d97470ce6fac0594dd007804d33432James Dong * Adds an external timed text source file (Uri). 190541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 190641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Currently supported format is SubRip with the file extension .srt, case insensitive. 19077a9734d769d97470ce6fac0594dd007804d33432James Dong * Note that a single external timed text source may contain multiple tracks in it. 190841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * One can find the total number of available tracks using {@link #getTrackInfo()} to see what 190941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * additional tracks become available after this method call. 191041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 191141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param context the Context to use when resolving the Uri 191241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param uri the Content URI of the data you want to play 1913831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @param mimeType The mime type of the file. Must be one of the mime types listed above. 1914831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IOException if the file cannot be accessed or is corrupted. 1915831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IllegalArgumentException if the mimeType is not supported. 19167a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 1917c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang */ 19187a9734d769d97470ce6fac0594dd007804d33432James Dong public void addTimedTextSource(Context context, Uri uri, String mimeType) 19197a9734d769d97470ce6fac0594dd007804d33432James Dong throws IOException, IllegalArgumentException, IllegalStateException { 192041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang String scheme = uri.getScheme(); 192141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if(scheme == null || scheme.equals("file")) { 19227a9734d769d97470ce6fac0594dd007804d33432James Dong addTimedTextSource(uri.getPath(), mimeType); 192341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return; 1924c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 192541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 192641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang AssetFileDescriptor fd = null; 192741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang try { 192841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang ContentResolver resolver = context.getContentResolver(); 192941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang fd = resolver.openAssetFileDescriptor(uri, "r"); 193041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (fd == null) { 193141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return; 193241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 19337a9734d769d97470ce6fac0594dd007804d33432James Dong addTimedTextSource(fd.getFileDescriptor(), mimeType); 193441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return; 193541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } catch (SecurityException ex) { 193641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } catch (IOException ex) { 193741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } finally { 193841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (fd != null) { 193941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang fd.close(); 194041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 194141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 1942c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 1943c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 194441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 19457a9734d769d97470ce6fac0594dd007804d33432James Dong * Adds an external timed text source file (FileDescriptor). 19467a9734d769d97470ce6fac0594dd007804d33432James Dong * 194741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * It is the caller's responsibility to close the file descriptor. 194841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * It is safe to do so as soon as this call returns. 194941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 19507a9734d769d97470ce6fac0594dd007804d33432James Dong * Currently supported format is SubRip. Note that a single external timed text source may 19517a9734d769d97470ce6fac0594dd007804d33432James Dong * contain multiple tracks in it. One can find the total number of available tracks 19527a9734d769d97470ce6fac0594dd007804d33432James Dong * using {@link #getTrackInfo()} to see what additional tracks become available 19537a9734d769d97470ce6fac0594dd007804d33432James Dong * after this method call. 195441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 195541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param fd the FileDescriptor for the file you want to play 1956831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @param mimeType The mime type of the file. Must be one of the mime types listed above. 1957831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IllegalArgumentException if the mimeType is not supported. 19587a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 195941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 19607a9734d769d97470ce6fac0594dd007804d33432James Dong public void addTimedTextSource(FileDescriptor fd, String mimeType) 19617a9734d769d97470ce6fac0594dd007804d33432James Dong throws IllegalArgumentException, IllegalStateException { 196241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang // intentionally less than LONG_MAX 19637a9734d769d97470ce6fac0594dd007804d33432James Dong addTimedTextSource(fd, 0, 0x7ffffffffffffffL, mimeType); 196441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 196541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 196641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 196741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Adds an external timed text file (FileDescriptor). 19687a9734d769d97470ce6fac0594dd007804d33432James Dong * 196941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * It is the caller's responsibility to close the file descriptor. 197041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * It is safe to do so as soon as this call returns. 197141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 19727a9734d769d97470ce6fac0594dd007804d33432James Dong * Currently supported format is SubRip. Note that a single external timed text source may 19737a9734d769d97470ce6fac0594dd007804d33432James Dong * contain multiple tracks in it. One can find the total number of available tracks 19747a9734d769d97470ce6fac0594dd007804d33432James Dong * using {@link #getTrackInfo()} to see what additional tracks become available 19757a9734d769d97470ce6fac0594dd007804d33432James Dong * after this method call. 197641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 197741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param fd the FileDescriptor for the file you want to play 197841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param offset the offset into the file where the data to be played starts, in bytes 197941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @param length the length in bytes of the data to be played 1980831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @param mimeType The mime type of the file. Must be one of the mime types listed above. 1981831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @throws IllegalArgumentException if the mimeType is not supported. 19827a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 198341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 19847a9734d769d97470ce6fac0594dd007804d33432James Dong public void addTimedTextSource(FileDescriptor fd, long offset, long length, String mimeType) 19857a9734d769d97470ce6fac0594dd007804d33432James Dong throws IllegalArgumentException, IllegalStateException { 198641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (!availableMimeTypeForExternalSource(mimeType)) { 19877a9734d769d97470ce6fac0594dd007804d33432James Dong throw new IllegalArgumentException("Illegal mimeType for timed text source: " + mimeType); 198841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 1989c4c0284e45e1b69a03309cd55f937bcc638c0becJames Dong 199041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel request = Parcel.obtain(); 199141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel reply = Parcel.obtain(); 1992be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang try { 1993be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInterfaceToken(IMEDIA_PLAYER); 1994be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD); 1995be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeFileDescriptor(fd); 1996be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeLong(offset); 1997be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeLong(length); 1998be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeString(mimeType); 1999be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang invoke(request, reply); 2000be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } finally { 2001be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.recycle(); 2002be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang reply.recycle(); 2003be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } 2004c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 2005c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 2006c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang /** 200741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Selects a track. 200841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <p> 2009831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * If a MediaPlayer is in invalid state, it throws an IllegalStateException exception. 2010831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * If a MediaPlayer is in <em>Started</em> state, the selected track is presented immediately. 201141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * If a MediaPlayer is not in Started state, it just marks the track to be played. 201241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * </p> 201341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <p> 201441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * In any valid state, if it is called multiple times on the same type of track (ie. Video, 201541f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * Audio, Timed Text), the most recent one will be chosen. 201641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * </p> 201741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * <p> 2018831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * The first audio and video tracks are selected by default if available, even though 2019831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * this method is not called. However, no timed text track will be selected until 2020831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * this function is called. 2021831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * </p> 2022831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * <p> 2023831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * Currently, only timed text tracks or audio tracks can be selected via this method. 2024831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * In addition, the support for selecting an audio track at runtime is pretty limited 2025831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * in that an audio track can only be selected in the <em>Prepared</em> state. 202641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * </p> 2027831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * @param index the index of the track to be selected. The valid range of the index 2028831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * is 0..total number of track - 1. The total number of tracks as well as the type of 2029831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * each individual track can be found by calling {@link #getTrackInfo()} method. 20307a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 20317a9734d769d97470ce6fac0594dd007804d33432James Dong * 20327a9734d769d97470ce6fac0594dd007804d33432James Dong * @see android.media.MediaPlayer#getTrackInfo 2033c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang */ 20347a9734d769d97470ce6fac0594dd007804d33432James Dong public void selectTrack(int index) throws IllegalStateException { 20357a9734d769d97470ce6fac0594dd007804d33432James Dong selectOrDeselectTrack(index, true /* select */); 203641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } 203741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 203841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** 20397a9734d769d97470ce6fac0594dd007804d33432James Dong * Deselect a track. 2040831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * <p> 2041831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * Currently, the track must be a timed text track and no audio or video tracks can be 20427a9734d769d97470ce6fac0594dd007804d33432James Dong * deselected. If the timed text track identified by index has not been 2043831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * selected before, it throws an exception. 2044831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * </p> 20457a9734d769d97470ce6fac0594dd007804d33432James Dong * @param index the index of the track to be deselected. The valid range of the index 2046831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * is 0..total number of tracks - 1. The total number of tracks as well as the type of 2047831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * each individual track can be found by calling {@link #getTrackInfo()} method. 20487a9734d769d97470ce6fac0594dd007804d33432James Dong * @throws IllegalStateException if called in an invalid state. 2049831f0a90cad923ec6b00c5c598ac4356e5849431James Dong * 20507a9734d769d97470ce6fac0594dd007804d33432James Dong * @see android.media.MediaPlayer#getTrackInfo 205141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 20527a9734d769d97470ce6fac0594dd007804d33432James Dong public void deselectTrack(int index) throws IllegalStateException { 20537a9734d769d97470ce6fac0594dd007804d33432James Dong selectOrDeselectTrack(index, false /* select */); 2054831f0a90cad923ec6b00c5c598ac4356e5849431James Dong } 2055831f0a90cad923ec6b00c5c598ac4356e5849431James Dong 20567a9734d769d97470ce6fac0594dd007804d33432James Dong private void selectOrDeselectTrack(int index, boolean select) 20577a9734d769d97470ce6fac0594dd007804d33432James Dong throws IllegalStateException { 2058d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar // handle subtitle track through subtitle controller 2059d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar SubtitleTrack track = null; 2060d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar if (index < mInbandSubtitleTracks.length) { 2061d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar track = mInbandSubtitleTracks[index]; 2062d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } else if (index < mInbandSubtitleTracks.length + mOutOfBandSubtitleTracks.size()) { 2063d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar track = mOutOfBandSubtitleTracks.get(index - mInbandSubtitleTracks.length); 2064d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } 2065d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar 2066d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar if (mSubtitleController != null && track != null) { 2067d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar if (select) { 2068d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mSubtitleController.selectTrack(track); 2069d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } else if (mSubtitleController.getSelectedTrack() == track) { 2070d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar mSubtitleController.selectTrack(null); 2071d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } else { 2072d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar Log.w(TAG, "trying to deselect track that was not selected"); 2073d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } 2074484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar return; 2075484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar } 2076484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 2077d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar selectOrDeselectInbandTrack(index, select); 2078d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar } 2079d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar 2080d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar private void selectOrDeselectInbandTrack(int index, boolean select) 2081d486f9656a6f9d6c056d84fce39f3db8d1614e1dLajos Molnar throws IllegalStateException { 208241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel request = Parcel.obtain(); 208341f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang Parcel reply = Parcel.obtain(); 2084be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang try { 2085be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInterfaceToken(IMEDIA_PLAYER); 2086be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK); 2087be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.writeInt(index); 2088be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang invoke(request, reply); 2089be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } finally { 2090be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang request.recycle(); 2091be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang reply.recycle(); 2092be0ea968bf8b3f92f6975ccd14031aec23a2c47fInsun Kang } 2093c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang } 2094c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang 2095831f0a90cad923ec6b00c5c598ac4356e5849431James Dong 2096c6091ddd3a22da98b5e83d4b5d864939b451b752Gloria Wang /** 2097d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang * @param reply Parcel with audio/video duration info for battery 2098d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang tracking usage 2099d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang * @return The status code. 2100d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang * {@hide} 2101d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang */ 2102d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang public native static int native_pullBatteryData(Parcel reply); 2103d211f41f764fe81fe00b10a99b4b44cb84479cbeGloria Wang 2104720aa282791ef9405d39a15f419a41ab24f11e30John Grossman /** 2105720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * Sets the target UDP re-transmit endpoint for the low level player. 2106720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * Generally, the address portion of the endpoint is an IP multicast 2107720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * address, although a unicast address would be equally valid. When a valid 2108720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * retransmit endpoint has been set, the media player will not decode and 2109720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * render the media presentation locally. Instead, the player will attempt 2110720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * to re-multiplex its media data using the Android@Home RTP profile and 2111720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * re-transmit to the target endpoint. Receiver devices (which may be 2112720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * either the same as the transmitting device or different devices) may 2113720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * instantiate, prepare, and start a receiver player using a setDataSource 2114720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * URL of the form... 2115720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * 2116720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * aahRX://<multicastIP>:<port> 2117720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * 2118720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * to receive, decode and render the re-transmitted content. 2119720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * 2120720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * setRetransmitEndpoint may only be called before setDataSource has been 2121720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * called; while the player is in the Idle state. 2122720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * 2123720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * @param endpoint the address and UDP port of the re-transmission target or 2124720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * null if no re-transmission is to be performed. 2125720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * @throws IllegalStateException if it is called in an invalid state 2126720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * @throws IllegalArgumentException if the retransmit endpoint is supplied, 2127720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * but invalid. 2128720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * 2129720aa282791ef9405d39a15f419a41ab24f11e30John Grossman * {@hide} pending API council 2130720aa282791ef9405d39a15f419a41ab24f11e30John Grossman */ 2131720aa282791ef9405d39a15f419a41ab24f11e30John Grossman public void setRetransmitEndpoint(InetSocketAddress endpoint) 2132720aa282791ef9405d39a15f419a41ab24f11e30John Grossman throws IllegalStateException, IllegalArgumentException 2133720aa282791ef9405d39a15f419a41ab24f11e30John Grossman { 2134720aa282791ef9405d39a15f419a41ab24f11e30John Grossman String addrString = null; 2135720aa282791ef9405d39a15f419a41ab24f11e30John Grossman int port = 0; 2136720aa282791ef9405d39a15f419a41ab24f11e30John Grossman 2137720aa282791ef9405d39a15f419a41ab24f11e30John Grossman if (null != endpoint) { 2138720aa282791ef9405d39a15f419a41ab24f11e30John Grossman addrString = endpoint.getAddress().getHostAddress(); 2139720aa282791ef9405d39a15f419a41ab24f11e30John Grossman port = endpoint.getPort(); 2140720aa282791ef9405d39a15f419a41ab24f11e30John Grossman } 2141720aa282791ef9405d39a15f419a41ab24f11e30John Grossman 2142720aa282791ef9405d39a15f419a41ab24f11e30John Grossman int ret = native_setRetransmitEndpoint(addrString, port); 2143720aa282791ef9405d39a15f419a41ab24f11e30John Grossman if (ret != 0) { 2144720aa282791ef9405d39a15f419a41ab24f11e30John Grossman throw new IllegalArgumentException("Illegal re-transmit endpoint; native ret " + ret); 2145720aa282791ef9405d39a15f419a41ab24f11e30John Grossman } 2146720aa282791ef9405d39a15f419a41ab24f11e30John Grossman } 2147720aa282791ef9405d39a15f419a41ab24f11e30John Grossman 2148720aa282791ef9405d39a15f419a41ab24f11e30John Grossman private native final int native_setRetransmitEndpoint(String addrString, int port); 2149720aa282791ef9405d39a15f419a41ab24f11e30John Grossman 21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { native_finalize(); } 21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Do not change these values without updating their counterparts 21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in include/media/mediaplayer.h! 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_NOP = 0; // interface test message 21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_PREPARED = 1; 21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_PLAYBACK_COMPLETE = 2; 21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_BUFFERING_UPDATE = 3; 21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_SEEK_COMPLETE = 4; 21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_SET_VIDEO_SIZE = 5; 21623d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int MEDIA_STARTED = 6; 21633d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int MEDIA_PAUSED = 7; 21643d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int MEDIA_STOPPED = 8; 2165d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar private static final int MEDIA_SKIPPED = 9; 2166162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang private static final int MEDIA_TIMED_TEXT = 99; 21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MEDIA_ERROR = 100; 2168c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project private static final int MEDIA_INFO = 200; 216983ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang private static final int MEDIA_SUBTITLE_DATA = 201; 21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21713d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private TimeProvider mTimeProvider; 21723d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 21733d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 21743d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public MediaTimeProvider getMediaTimeProvider() { 2175a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mTimeProvider == null) { 2176a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mTimeProvider = new TimeProvider(this); 2177a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 21783d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return mTimeProvider; 21793d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 21803d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class EventHandler extends Handler 21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MediaPlayer mMediaPlayer; 21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public EventHandler(MediaPlayer mp, Looper looper) { 21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(looper); 21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMediaPlayer = mp; 21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMediaPlayer.mNativeContext == 0) { 21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "mediaplayer went away with unhandled events"); 21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(msg.what) { 21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_PREPARED: 2198484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar scanInternalSubtitleTracks(); 21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnPreparedListener != null) 22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnPreparedListener.onPrepared(mMediaPlayer); 22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_PLAYBACK_COMPLETE: 22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnCompletionListener != null) 22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCompletionListener.onCompletion(mMediaPlayer); 22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22093d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case MEDIA_STOPPED: 22103d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mTimeProvider != null) { 22113d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeProvider.onStopped(); 22123d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 22133d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 22143d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 22153d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case MEDIA_STARTED: 22163d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case MEDIA_PAUSED: 22173d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mTimeProvider != null) { 22183d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeProvider.onPaused(msg.what == MEDIA_PAUSED); 22193d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 22203d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 22213d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_BUFFERING_UPDATE: 22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnBufferingUpdateListener != null) 22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1); 22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_SEEK_COMPLETE: 22283d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mOnSeekCompleteListener != null) { 22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnSeekCompleteListener.onSeekComplete(mMediaPlayer); 22303d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 2231d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar // fall through 2232d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar 2233d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar case MEDIA_SKIPPED: 22343d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mTimeProvider != null) { 22353d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeProvider.onSeekComplete(mMediaPlayer); 22363d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_SET_VIDEO_SIZE: 22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnVideoSizeChangedListener != null) 22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnVideoSizeChangedListener.onVideoSizeChanged(mMediaPlayer, msg.arg1, msg.arg2); 22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_ERROR: 22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")"); 22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean error_was_handled = false; 22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnErrorListener != null) { 22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project error_was_handled = mOnErrorListener.onError(mMediaPlayer, msg.arg1, msg.arg2); 22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnCompletionListener != null && ! error_was_handled) { 22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnCompletionListener.onCompletion(mMediaPlayer); 22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stayAwake(false); 22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2255c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2256c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project case MEDIA_INFO: 2257484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar switch (msg.arg1) { 2258484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar case MEDIA_INFO_VIDEO_TRACK_LAGGING: 225952c7832e35b6f0c7d6197eb09346cea7dc5bea6bAndreas Huber Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")"); 2260484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar break; 2261484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar case MEDIA_INFO_METADATA_UPDATE: 2262484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar scanInternalSubtitleTracks(); 22639d480895956632ab388c7ee62d9f902910a198fbLajos Molnar // fall through 22649d480895956632ab388c7ee62d9f902910a198fbLajos Molnar 2265484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar case MEDIA_INFO_EXTERNAL_METADATA_UPDATE: 2266484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar msg.arg1 = MEDIA_INFO_METADATA_UPDATE; 22679d480895956632ab388c7ee62d9f902910a198fbLajos Molnar // update default track selection 22689d480895956632ab388c7ee62d9f902910a198fbLajos Molnar mSubtitleController.selectDefaultTrack(); 2269484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar break; 227052c7832e35b6f0c7d6197eb09346cea7dc5bea6bAndreas Huber } 2271484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 2272c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOnInfoListener != null) { 2273c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2); 2274c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 2275c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project // No real default action so far. 2276c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project return; 2277162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang case MEDIA_TIMED_TEXT: 227841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (mOnTimedTextListener == null) 227941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang return; 228041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang if (msg.obj == null) { 228141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang mOnTimedTextListener.onTimedText(mMediaPlayer, null); 228241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang } else { 22838902097bb686752ff207e3bda12713be1a8c74ebInsun Kang if (msg.obj instanceof Parcel) { 22848902097bb686752ff207e3bda12713be1a8c74ebInsun Kang Parcel parcel = (Parcel)msg.obj; 22858902097bb686752ff207e3bda12713be1a8c74ebInsun Kang TimedText text = new TimedText(parcel); 2286333c09945e7399c6a2b1f4d9fdf981508e38db52Insun Kang parcel.recycle(); 228741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang mOnTimedTextListener.onTimedText(mMediaPlayer, text); 2288eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang } 2289162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang } 2290162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang return; 2291c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 229283ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang case MEDIA_SUBTITLE_DATA: 229383ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang if (mOnSubtitleDataListener == null) { 229483ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang return; 229583ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang } 229683ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang if (msg.obj instanceof Parcel) { 229783ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang Parcel parcel = (Parcel) msg.obj; 229883ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang SubtitleData data = new SubtitleData(parcel); 229983ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang parcel.recycle(); 230083ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang mOnSubtitleDataListener.onSubtitleData(mMediaPlayer, data); 230183ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang } 230283ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang return; 230383ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang 23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MEDIA_NOP: // interface test message - ignore 23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Unknown message type " + msg.what); 23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 231441f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /* 23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called from native code when an interesting event happens. This method 23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * just uses the EventHandler system to post the event back to the main app thread. 23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We use a weak reference to the original MediaPlayer object so that the native 23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * code is safe from the object disappearing from underneath it. (This is 23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the cookie passed to native_setup().) 23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void postEventFromNative(Object mediaplayer_ref, 23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int what, int arg1, int arg2, Object obj) 23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get(); 23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mp == null) { 23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 232984b832054552e00257bb04997143ca33d6d100beMarco Nelissen if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) { 233084b832054552e00257bb04997143ca33d6d100beMarco Nelissen // this acquires the wakelock if needed, and sets the client side state 233184b832054552e00257bb04997143ca33d6d100beMarco Nelissen mp.start(); 233284b832054552e00257bb04997143ca33d6d100beMarco Nelissen } 23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mp.mEventHandler != null) { 23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj); 23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mp.mEventHandler.sendMessage(m); 23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when the media 23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * source is ready for playback. 23429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnPreparedListener 23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the media file is ready for playback. 234732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer that is ready for playback 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onPrepared(MediaPlayer mp); 23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the media source is ready 23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for playback. 23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2357105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @param listener the callback that will be run 23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2359105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project public void setOnPreparedListener(OnPreparedListener listener) 23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2361105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnPreparedListener = listener; 23629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnPreparedListener mOnPreparedListener; 23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when playback of 23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a media source has completed. 23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnCompletionListener 23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when the end of a media source is reached during playback. 237432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer that reached the end of the file 23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onCompletion(MediaPlayer mp); 23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the end of a media source 23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been reached during playback. 23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2384105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @param listener the callback that will be run 23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2386105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project public void setOnCompletionListener(OnCompletionListener listener) 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2388105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnCompletionListener = listener; 23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnCompletionListener mOnCompletionListener; 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition of a callback to be invoked indicating buffering 23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * status of a media resource being streamed over the network. 23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnBufferingUpdateListener 23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2400ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * Called to update status in buffering a media stream received through 2401ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * progressive HTTP download. The received buffering percentage 2402ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * indicates how much of the content has been buffered or played. 2403ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * For example a buffering update of 80 percent when half the content 2404ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * has already been played indicates that the next 30 percent of the 2405ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * content to play has been buffered. 240632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer the update pertains to 2408ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * @param percent the percentage (0-100) of the content 2409ea763069b1dca16193d32c6cf3ceab1c23743271Jean-Michel Trivi * that has been buffered or played thus far 24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onBufferingUpdate(MediaPlayer mp, int percent); 24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 241332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the status of a network 24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stream's buffer has changed. 24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2418105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @param listener the callback that will be run. 24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2420105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener) 24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2422105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnBufferingUpdateListener = listener; 24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnBufferingUpdateListener mOnBufferingUpdateListener; 242632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition of a callback to be invoked indicating 24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the completion of a seek operation. 24309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnSeekCompleteListener 24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called to indicate the completion of a seek operation. 243532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer that issued the seek operation 24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSeekComplete(MediaPlayer mp); 24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 244032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when a seek operation has been 24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completed. 244432f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2445105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @param listener the callback that will be run 24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2447105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project public void setOnSeekCompleteListener(OnSeekCompleteListener listener) 24489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2449105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnSeekCompleteListener = listener; 24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 245132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnSeekCompleteListener mOnSeekCompleteListener; 24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition of a callback to be invoked when the 24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * video size is first known or updated 24579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnVideoSizeChangedListener 24599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 24609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called to indicate the video size 246232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2463ca402cdcacfdcd2978a22d59f446c93aad34c75eJames Dong * The video size (width and height) could be 0 if there was no video, 2464ca402cdcacfdcd2978a22d59f446c93aad34c75eJames Dong * no display surface was set, or the value was not determined yet. 2465ca402cdcacfdcd2978a22d59f446c93aad34c75eJames Dong * 24669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer associated with this callback 24679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the width of the video 24689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the height of the video 24699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onVideoSizeChanged(MediaPlayer mp, int width, int height); 24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 247232f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when the video size is 24759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * known or updated. 247632f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2477105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @param listener the callback that will be run 24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2479105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener) 24809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2481105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mOnVideoSizeChangedListener = listener; 24829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 248332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 24849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnVideoSizeChangedListener mOnVideoSizeChangedListener; 24859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2486162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang /** 2487162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * Interface definition of a callback to be invoked when a 2488162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * timed text is available for display. 2489162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang */ 2490162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang public interface OnTimedTextListener 2491162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang { 2492162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang /** 2493eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang * Called to indicate an avaliable timed text 2494162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * 2495162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * @param mp the MediaPlayer associated with this callback 2496eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang * @param text the timed text sample which contains the text 2497eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang * needed to be displayed and the display format. 2498162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang */ 2499eaa5d8f9c0117bdaa20fd0a57921156bb0c06345Gloria Wang public void onTimedText(MediaPlayer mp, TimedText text); 2500162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang } 2501162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang 2502162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang /** 2503162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * Register a callback to be invoked when a timed text is available 2504162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * for display. 2505162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * 2506162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang * @param listener the callback that will be run 2507162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang */ 2508162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang public void setOnTimedTextListener(OnTimedTextListener listener) 2509162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang { 2510162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang mOnTimedTextListener = listener; 2511162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang } 2512162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang 2513162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang private OnTimedTextListener mOnTimedTextListener; 2514162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang 251583ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang /** 251683ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * Interface definition of a callback to be invoked when a 251783ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * track has data available. 251883ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * 251983ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * @hide 252083ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang */ 252183ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang public interface OnSubtitleDataListener 252283ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang { 252383ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang public void onSubtitleData(MediaPlayer mp, SubtitleData data); 252483ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang } 252583ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang 252683ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang /** 252783ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * Register a callback to be invoked when a track has data available. 252883ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * 252983ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * @param listener the callback that will be run 253083ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * 253183ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang * @hide 253283ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang */ 253383ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang public void setOnSubtitleDataListener(OnSubtitleDataListener listener) 253483ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang { 253583ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang mOnSubtitleDataListener = listener; 253683ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang } 253783ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang 253883ddaf664c7a9eb2759269ec75d25dba48edebf2Chong Zhang private OnSubtitleDataListener mOnSubtitleDataListener; 2539162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang 25409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Do not change these values without updating their counterparts 25419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in include/media/mediaplayer.h! 25429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Unspecified media player error. 25449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.media.MediaPlayer.OnErrorListener 25459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MEDIA_ERROR_UNKNOWN = 1; 2547c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 25489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Media server died. In this case, the application must release the 254932f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * MediaPlayer object and instantiate a new one. 25509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.media.MediaPlayer.OnErrorListener 25519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MEDIA_ERROR_SERVER_DIED = 100; 255332f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 2554c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** The video is streamed and its container is not valid for progressive 2555c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * playback i.e the video's index (e.g moov atom) is not at the start of the 2556c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * file. 25574a0029f95db144ba735b35e636400e8ce535383fNiko Catania * @see android.media.MediaPlayer.OnErrorListener 2558c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2559c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200; 25609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25612adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong /** File or network related operation errors. */ 25622adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong public static final int MEDIA_ERROR_IO = -1004; 25632adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong /** Bitstream is not conforming to the related coding standard or file spec. */ 25642adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong public static final int MEDIA_ERROR_MALFORMED = -1007; 25652adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong /** Bitstream is conforming to the related coding standard or file spec, but 25662adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * the media framework does not support the feature. */ 25672adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong public static final int MEDIA_ERROR_UNSUPPORTED = -1010; 25682adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong /** Some operation takes too long to complete, usually more than 3-5 seconds. */ 25692adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong public static final int MEDIA_ERROR_TIMED_OUT = -110; 25702adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong 25719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 25729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition of a callback to be invoked when there 25739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been an error during an asynchronous operation (other errors 25749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will throw exceptions at method call time). 25759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnErrorListener 25779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 25789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 25799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called to indicate an error. 258032f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 25819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mp the MediaPlayer the error pertains to 25829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param what the type of error that has occurred: 25839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 25849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>{@link #MEDIA_ERROR_UNKNOWN} 25859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>{@link #MEDIA_ERROR_SERVER_DIED} 25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2587c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param extra an extra code, specific to the error. Typically 2588b10ec1f4b1f6a3552060d44359dd64cc37b1a497James Dong * implementation dependent. 25892adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * <ul> 25902adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * <li>{@link #MEDIA_ERROR_IO} 25912adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * <li>{@link #MEDIA_ERROR_MALFORMED} 25922adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * <li>{@link #MEDIA_ERROR_UNSUPPORTED} 25932adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * <li>{@link #MEDIA_ERROR_TIMED_OUT} 25942adac496a891ba70cc2797a36aacf642e10b8c8dJames Dong * </ul> 25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if the method handled the error, false if it didn't. 25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returning false, or not having an OnErrorListener at all, will 25979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cause the OnCompletionListener to be called. 25989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onError(MediaPlayer mp, int what, int extra); 26009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 260132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania 26029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 26039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register a callback to be invoked when an error has happened 26049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * during an asynchronous operation. 260532f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2606c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param listener the callback that will be run 26079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2608c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public void setOnErrorListener(OnErrorListener listener) 26099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2610c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mOnErrorListener = listener; 26119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 26129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnErrorListener mOnErrorListener; 2614c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2615c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2616c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /* Do not change these values without updating their counterparts 2617c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * in include/media/mediaplayer.h! 2618c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2619c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** Unspecified media player info. 2620c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @see android.media.MediaPlayer.OnInfoListener 2621c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2622c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public static final int MEDIA_INFO_UNKNOWN = 1; 2623c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 262484b832054552e00257bb04997143ca33d6d100beMarco Nelissen /** The player was started because it was used as the next player for another 262584b832054552e00257bb04997143ca33d6d100beMarco Nelissen * player, which just completed playback. 262684b832054552e00257bb04997143ca33d6d100beMarco Nelissen * @see android.media.MediaPlayer.OnInfoListener 262784b832054552e00257bb04997143ca33d6d100beMarco Nelissen * @hide 262884b832054552e00257bb04997143ca33d6d100beMarco Nelissen */ 262984b832054552e00257bb04997143ca33d6d100beMarco Nelissen public static final int MEDIA_INFO_STARTED_AS_NEXT = 2; 263084b832054552e00257bb04997143ca33d6d100beMarco Nelissen 263115a89e6b48e9cd0112efcfd903843c5912e26567James Dong /** The player just pushed the very first video frame for rendering. 263215a89e6b48e9cd0112efcfd903843c5912e26567James Dong * @see android.media.MediaPlayer.OnInfoListener 263315a89e6b48e9cd0112efcfd903843c5912e26567James Dong */ 263415a89e6b48e9cd0112efcfd903843c5912e26567James Dong public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; 263515a89e6b48e9cd0112efcfd903843c5912e26567James Dong 2636c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** The video is too complex for the decoder: it can't decode frames fast 2637c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * enough. Possibly only the audio plays fine at this stage. 2638c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @see android.media.MediaPlayer.OnInfoListener 2639c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2640c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; 2641c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 26424d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber /** MediaPlayer is temporarily pausing playback internally in order to 26434d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber * buffer more data. 2644c36b3c6956479f1a154fe1e08b679ff4657097e1James Dong * @see android.media.MediaPlayer.OnInfoListener 26454d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber */ 26464d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber public static final int MEDIA_INFO_BUFFERING_START = 701; 26474d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber 26484d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber /** MediaPlayer is resuming playback after filling buffers. 2649c36b3c6956479f1a154fe1e08b679ff4657097e1James Dong * @see android.media.MediaPlayer.OnInfoListener 26504d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber */ 26514d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber public static final int MEDIA_INFO_BUFFERING_END = 702; 26524d61f602bf67fe61256c23f090d6119992ad5160Andreas Huber 2653c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** Bad interleaving means that a media has been improperly interleaved or 2654c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * not interleaved at all, e.g has all the video samples first then all the 2655c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * audio ones. Video is playing but a lot of disk seeks may be happening. 2656c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @see android.media.MediaPlayer.OnInfoListener 2657c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2658c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; 2659c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2660c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** The media cannot be seeked (e.g live stream) 2661c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @see android.media.MediaPlayer.OnInfoListener 2662c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2663c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public static final int MEDIA_INFO_NOT_SEEKABLE = 801; 2664c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 26659193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania /** A new set of metadata is available. 26669193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * @see android.media.MediaPlayer.OnInfoListener 26679193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania */ 26689193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania public static final int MEDIA_INFO_METADATA_UPDATE = 802; 26699193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania 2670484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar /** A new set of external-only metadata is available. Used by 2671484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar * JAVA framework to avoid triggering track scanning. 2672484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar * @hide 2673484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar */ 2674484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803; 2675484ff7a92298eaeb5e7edc39895b3a26bed704b3Lajos Molnar 267641f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang /** Failed to handle timed text track properly. 267741f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * @see android.media.MediaPlayer.OnInfoListener 267841f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * 267941f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang * {@hide} 268041f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang */ 268141f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900; 268241f3f716b07265fb355ef70e89b9d7e1ad5f0a6fInsun Kang 2683af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar /** Subtitle track was not supported by the media framework. 2684af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar * @see android.media.MediaPlayer.OnInfoListener 2685af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar */ 2686af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; 2687af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar 2688af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar /** Reading the subtitle track takes too long. 2689af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar * @see android.media.MediaPlayer.OnInfoListener 2690af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar */ 2691af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; 2692af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar 2693c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** 2694c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Interface definition of a callback to be invoked to communicate some 2695c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * info and/or warning about the media or its playback. 2696c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2697c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public interface OnInfoListener 2698c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project { 2699c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** 2700c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Called to indicate an info or a warning. 270132f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2702c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param mp the MediaPlayer the info pertains to. 2703c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param what the type of info or warning. 2704c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <ul> 2705c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>{@link #MEDIA_INFO_UNKNOWN} 2706c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING} 270715a89e6b48e9cd0112efcfd903843c5912e26567James Dong * <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START} 2708c36b3c6956479f1a154fe1e08b679ff4657097e1James Dong * <li>{@link #MEDIA_INFO_BUFFERING_START} 2709c36b3c6956479f1a154fe1e08b679ff4657097e1James Dong * <li>{@link #MEDIA_INFO_BUFFERING_END} 2710c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>{@link #MEDIA_INFO_BAD_INTERLEAVING} 2711c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>{@link #MEDIA_INFO_NOT_SEEKABLE} 27129193e08dc1d91401fdf1846eaad4689da3911dc1Nicolas Catania * <li>{@link #MEDIA_INFO_METADATA_UPDATE} 2713af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar * <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE} 2714af309824350d6b2fd38e19ef9104211e5ba132e8Lajos Molnar * <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT} 2715c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * </ul> 2716c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param extra an extra code, specific to the info. Typically 2717b10ec1f4b1f6a3552060d44359dd64cc37b1a497James Dong * implementation dependent. 2718c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @return True if the method handled the info, false if it didn't. 2719c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Returning false, or not having an OnErrorListener at all, will 2720c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * cause the info to be discarded. 2721c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2722c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project boolean onInfo(MediaPlayer mp, int what, int extra); 2723c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 2724c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2725c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project /** 2726c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Register a callback to be invoked when an info/warning is available. 272732f82774884bdd709789ab9f3ccdf5b972ff7681Nicolas Catania * 2728c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @param listener the callback that will be run 2729c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project */ 2730c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public void setOnInfoListener(OnInfoListener listener) 2731c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project { 2732c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mOnInfoListener = listener; 2733c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 2734c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 2735c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project private OnInfoListener mOnInfoListener; 2736c39d2e3c012fb96999991e30659a474f9f30f789Marco Nelissen 2737454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong /* 2738454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong * Test whether a given video scaling mode is supported. 2739454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong */ 2740454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong private boolean isVideoScalingModeSupported(int mode) { 2741454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT || 2742454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); 2743454014e55fe5a0d9a4b47080f8017b5297d016a8James Dong } 2744d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2745d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private Context mProxyContext = null; 2746d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private ProxyReceiver mProxyReceiver = null; 2747d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2748d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private void setupProxyListener(Context context) { 2749d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber IntentFilter filter = new IntentFilter(); 2750d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber filter.addAction(Proxy.PROXY_CHANGE_ACTION); 2751d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber mProxyReceiver = new ProxyReceiver(); 2752d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber mProxyContext = context; 2753d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2754d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber Intent currentProxy = 2755d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber context.getApplicationContext().registerReceiver(mProxyReceiver, filter); 2756d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2757d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (currentProxy != null) { 2758d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber handleProxyBroadcast(currentProxy); 2759d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2760d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2761d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2762d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private void disableProxyListener() { 2763d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (mProxyReceiver == null) { 2764d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber return; 2765d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2766d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2767d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber Context appContext = mProxyContext.getApplicationContext(); 2768d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (appContext != null) { 2769d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber appContext.unregisterReceiver(mProxyReceiver); 2770d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2771d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2772d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber mProxyReceiver = null; 2773d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber mProxyContext = null; 2774d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2775d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2776d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private void handleProxyBroadcast(Intent intent) { 2777d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber ProxyProperties props = 2778d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO); 2779d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2780d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (props == null || props.getHost() == null) { 2781d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber updateProxyConfig(null); 2782d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } else { 2783d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber updateProxyConfig(props); 2784d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2785d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2786d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2787d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private class ProxyReceiver extends BroadcastReceiver { 2788d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber @Override 2789d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber public void onReceive(Context context, Intent intent) { 2790d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { 2791d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber handleProxyBroadcast(intent); 2792d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2793d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2794d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber } 2795d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber 2796d5f9fa574da2ee210ac86154ab0aea9fee5e8278Andreas Huber private native void updateProxyConfig(ProxyProperties props); 27973d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 27983d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 27993d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar static class TimeProvider implements MediaPlayer.OnSeekCompleteListener, 28003d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar MediaTimeProvider { 28013d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final String TAG = "MTP"; 28023d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L; 28033d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final long MAX_EARLY_CALLBACK_US = 1000; 28043d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final long TIME_ADJUSTMENT_RATE = 2; /* meaning 1/2 */ 28053d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long mLastTimeUs = 0; 28063d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private MediaPlayer mPlayer; 28073d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private boolean mPaused = true; 28083d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private boolean mStopped = true; 28093d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long mLastReportedTime; 28103d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long mTimeAdjustment; 28113d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // since we are expecting only a handful listeners per stream, there is 28123d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // no need for log(N) search performance 28133d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private MediaTimeProvider.OnMediaTimeListener mListeners[]; 28143d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long mTimes[]; 28153d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long mLastNanoTime; 28163d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private Handler mEventHandler; 28173d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private boolean mRefresh = false; 28183d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private boolean mPausing = false; 2819d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar private boolean mSeeking = false; 28203d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int NOTIFY = 1; 28213d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int NOTIFY_TIME = 0; 28223d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int REFRESH_AND_NOTIFY_TIME = 1; 28233d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int NOTIFY_STOP = 2; 28243d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private static final int NOTIFY_SEEK = 3; 2825a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar private HandlerThread mHandlerThread; 28263d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 28273d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 28283d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public boolean DEBUG = false; 28293d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 28303d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public TimeProvider(MediaPlayer mp) { 28313d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPlayer = mp; 28323d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar try { 28333d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar getCurrentTimeUs(true, false); 28343d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } catch (IllegalStateException e) { 28353d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // we assume starting position 28363d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mRefresh = true; 28373d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 2838a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar 2839a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar Looper looper; 2840a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if ((looper = Looper.myLooper()) == null && 2841a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar (looper = Looper.getMainLooper()) == null) { 2842a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar // Create our own looper here in case MP was created without one 2843a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mHandlerThread = new HandlerThread("MediaPlayerMTPEventThread", 2844a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar Process.THREAD_PRIORITY_FOREGROUND); 2845a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mHandlerThread.start(); 2846a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar looper = mHandlerThread.getLooper(); 2847a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 2848a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mEventHandler = new EventHandler(looper); 2849a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar 28503d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mListeners = new MediaTimeProvider.OnMediaTimeListener[0]; 28513d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes = new long[0]; 28523d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mLastTimeUs = 0; 28533d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeAdjustment = 0; 28543d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 28553d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 28563d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private void scheduleNotification(int type, long delayUs) { 2857d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar // ignore time notifications until seek is handled 2858d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar if (mSeeking && 2859d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar (type == NOTIFY_TIME || type == REFRESH_AND_NOTIFY_TIME)) { 2860d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar return; 2861d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar } 2862d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar 28633d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs); 28643d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mEventHandler.removeMessages(NOTIFY); 28653d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0); 28663d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000)); 28673d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 28683d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 28693d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 28703d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void close() { 28713d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mEventHandler.removeMessages(NOTIFY); 2872a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mHandlerThread != null) { 2873a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mHandlerThread.quitSafely(); 2874a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mHandlerThread = null; 2875a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 2876a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 2877a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar 2878a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar /** @hide */ 2879a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar protected void finalize() { 2880a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar if (mHandlerThread != null) { 2881a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar mHandlerThread.quitSafely(); 2882a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 28833d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 28843d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 28853d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 28863d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void onPaused(boolean paused) { 28873d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 28883d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "onPaused: " + paused); 28893d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mStopped) { // handle as seek if we were stopped 28904de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mStopped = false; 28914de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = true; 28923d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_SEEK, 0 /* delay */); 28933d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 28943d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPausing = paused; // special handling if player disappeared 28954de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = false; 28963d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */); 28973d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 28983d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 28993d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29003d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29013d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 29023d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void onStopped() { 29033d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 29043d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "onStopped"); 29053d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPaused = true; 29064de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mStopped = true; 29074de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = false; 29083d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_STOP, 0 /* delay */); 29093d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29103d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29113d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29123d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 29133d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar @Override 29143d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void onSeekComplete(MediaPlayer mp) { 29153d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 29164de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mStopped = false; 29174de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = true; 29183d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_SEEK, 0 /* delay */); 29193d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29203d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29213d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29223d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /** @hide */ 29233d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void onNewPlayer() { 29243d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mRefresh) { 29253d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 29264de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mStopped = false; 29274de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = true; 29283d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_SEEK, 0 /* delay */); 29293d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29303d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29313d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29323d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29333d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private synchronized void notifySeek() { 2934d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar mSeeking = false; 29353d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar try { 29363d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long timeUs = getCurrentTimeUs(true, false); 29373d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs); 29383d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29393d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) { 29403d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (listener == null) { 29413d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 29423d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29433d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar listener.onSeek(timeUs); 29443d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29453d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } catch (IllegalStateException e) { 29463d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // we should not be there, but at least signal pause 29473d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "onSeekComplete but no player"); 29483d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPausing = true; // special handling if player disappeared 29493d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar notifyTimedEvent(false /* refreshTime */); 29503d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29513d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29523d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29533d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private synchronized void notifyStop() { 29543d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) { 29553d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (listener == null) { 29563d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 29573d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29583d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar listener.onStop(); 29593d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29603d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29613d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29623d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) { 29633d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar int i = 0; 29643d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (; i < mListeners.length; i++) { 29653d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mListeners[i] == listener || mListeners[i] == null) { 29663d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 29673d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29683d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29693d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29703d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // new listener 29713d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (i >= mListeners.length) { 29723d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar MediaTimeProvider.OnMediaTimeListener[] newListeners = 29733d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar new MediaTimeProvider.OnMediaTimeListener[i + 1]; 29743d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long[] newTimes = new long[i + 1]; 29753d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length); 29763d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length); 29773d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mListeners = newListeners; 29783d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes = newTimes; 29793d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29803d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29813d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mListeners[i] == null) { 29823d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mListeners[i] = listener; 29833d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes[i] = MediaTimeProvider.NO_TIME; 29843d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29853d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return i; 29863d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29873d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29883d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void notifyAt( 29893d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long timeUs, MediaTimeProvider.OnMediaTimeListener listener) { 29903d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 29913d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "notifyAt " + timeUs); 29923d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes[registerListener(listener)] = timeUs; 29933d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_TIME, 0 /* delay */); 29943d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29953d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 29963d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 29973d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) { 29983d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 29993d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "scheduleUpdate"); 30003d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar int i = registerListener(listener); 30013d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30023d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mStopped) { 30033d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_STOP, 0 /* delay */); 30043d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 30053d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes[i] = 0; 30063d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_TIME, 0 /* delay */); 30073d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30083d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30093d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30103d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30113d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void cancelNotifications( 30123d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar MediaTimeProvider.OnMediaTimeListener listener) { 30133d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized(this) { 30143d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar int i = 0; 30153d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (; i < mListeners.length; i++) { 30163d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mListeners[i] == listener) { 30173d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar System.arraycopy(mListeners, i + 1, 30183d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mListeners, i, mListeners.length - i - 1); 30193d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar System.arraycopy(mTimes, i + 1, 30203d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes, i, mTimes.length - i - 1); 30213d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mListeners[mListeners.length - 1] = null; 30223d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes[mTimes.length - 1] = NO_TIME; 30233d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 30243d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else if (mListeners[i] == null) { 30253d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 30263d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30273d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30283d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30293d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_TIME, 0 /* delay */); 30303d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30313d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30323d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30333d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private synchronized void notifyTimedEvent(boolean refreshTime) { 30343d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // figure out next callback 30353d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long nowUs; 30363d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar try { 30373d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar nowUs = getCurrentTimeUs(refreshTime, true); 30383d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } catch (IllegalStateException e) { 30393d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // assume we paused until new player arrives 30403d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mRefresh = true; 30413d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPausing = true; // this ensures that call succeeds 30423d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar nowUs = getCurrentTimeUs(refreshTime, true); 30433d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30443d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long nextTimeUs = nowUs; 30453d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 3046d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar if (mSeeking) { 3047d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar // skip timed-event notifications until seek is complete 3048d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar return; 3049d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar } 3050d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar 30513d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) { 30523d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar StringBuilder sb = new StringBuilder(); 30533d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ") 30543d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar .append(nowUs).append(") from {"); 30553d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar boolean first = true; 30563d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (long time: mTimes) { 30573d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (time == NO_TIME) { 30583d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar continue; 30593d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30603d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (!first) sb.append(", "); 30613d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar sb.append(time); 30623d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar first = false; 30633d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30643d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar sb.append("}"); 30653d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar Log.d(TAG, sb.toString()); 30663d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30673d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30683d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners = 30693d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar new Vector<MediaTimeProvider.OnMediaTimeListener>(); 30703d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (int ix = 0; ix < mTimes.length; ix++) { 30713d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mListeners[ix] == null) { 30723d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 30733d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30743d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mTimes[ix] <= NO_TIME) { 30753d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // ignore, unless we were stopped 30763d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) { 30773d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar activatedListeners.add(mListeners[ix]); 30783d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "removed"); 30793d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimes[ix] = NO_TIME; 30803d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) { 30813d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar nextTimeUs = mTimes[ix]; 30823d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30833d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30843d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30853d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (nextTimeUs > nowUs && !mPaused) { 30863d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // schedule callback at nextTimeUs 30873d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs); 30883d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs); 30893d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 30903d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mEventHandler.removeMessages(NOTIFY); 30913d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // no more callbacks 30923d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30933d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30943d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) { 30953d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar listener.onTimedEvent(nowUs); 30963d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30973d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 30983d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 30993d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private long getEstimatedTime(long nanoTime, boolean monotonic) { 31003d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mPaused) { 31013d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mLastReportedTime = mLastTimeUs + mTimeAdjustment; 31023d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 31033d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long timeSinceRead = (nanoTime - mLastNanoTime) / 1000; 31043d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mLastReportedTime = mLastTimeUs + timeSinceRead; 31053d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mTimeAdjustment > 0) { 31063d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long adjustment = 31073d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE; 31083d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (adjustment <= 0) { 31093d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeAdjustment = 0; 31103d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 31113d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mLastReportedTime += adjustment; 31123d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31133d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31143d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31153d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return mLastReportedTime; 31163d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31173d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 31183d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public long getCurrentTimeUs(boolean refreshTime, boolean monotonic) 31193d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar throws IllegalStateException { 31203d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar synchronized (this) { 31213d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // we always refresh the time when the paused-state changes, because 31223d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // we expect to have received the pause-change event delayed. 31233d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mPaused && !refreshTime) { 31243d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return mLastReportedTime; 31253d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31263d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 31273d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar long nanoTime = System.nanoTime(); 31283d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (refreshTime || 31293d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) { 31303d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar try { 31310cab07d78844b71caa2b33d2fac3ab85de77ac2aLajos Molnar mLastTimeUs = mPlayer.getCurrentPosition() * 1000L; 31323d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPaused = !mPlayer.isPlaying(); 31333d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs); 31343d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } catch (IllegalStateException e) { 31353d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (mPausing) { 31363d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // if we were pausing, get last estimated timestamp 31373d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPausing = false; 31383d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar getEstimatedTime(nanoTime, monotonic); 31393d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mPaused = true; 31403d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime); 31413d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return mLastReportedTime; 31423d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31433d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar // TODO get time when prepared 31443d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar throw e; 31453d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31463d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mLastNanoTime = nanoTime; 31473d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (monotonic && mLastTimeUs < mLastReportedTime) { 31483d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar /* have to adjust time */ 31493d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeAdjustment = mLastReportedTime - mLastTimeUs; 3150d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar if (mTimeAdjustment > 1000000) { 3151d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar // schedule seeked event if time jumped significantly 3152d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar // TODO: do this properly by introducing an exception 31534de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mStopped = false; 31544de8e7c1a55f024361786e9fe03fa6eec1db6cb7Lajos Molnar mSeeking = true; 3155d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar scheduleNotification(NOTIFY_SEEK, 0 /* delay */); 3156d58b122208a7ce7dacc92bd729c0cb1fe0a5056aLajos Molnar } 31573d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } else { 31583d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar mTimeAdjustment = 0; 31593d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31603d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31613d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 31623d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar return getEstimatedTime(nanoTime, monotonic); 31633d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31643d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31653d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar 31663d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar private class EventHandler extends Handler { 3167a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar public EventHandler(Looper looper) { 3168a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar super(looper); 3169a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar } 3170a67a4439cacdaa04cb53566b77053694b26d06adLajos Molnar 31713d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar @Override 31723d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar public void handleMessage(Message msg) { 31733d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar if (msg.what == NOTIFY) { 31743d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar switch (msg.arg1) { 31753d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case NOTIFY_TIME: 31763d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar notifyTimedEvent(false /* refreshTime */); 31773d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 31783d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case REFRESH_AND_NOTIFY_TIME: 31793d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar notifyTimedEvent(true /* refreshTime */); 31803d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 31813d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case NOTIFY_STOP: 31823d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar notifyStop(); 31833d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 31843d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar case NOTIFY_SEEK: 31853d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar notifySeek(); 31863d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar break; 31873d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31883d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31893d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31903d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31913d99856f80ca23ce4e10bb3efcf7cefc65ff7337Lajos Molnar } 31929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3193