西安做网站,陕西西安网站建设公司排名,做网站 用什么语言,郑州短视频运营2019独角兽企业重金招聘Python工程师标准 客户端进程需要实现#xff0c;其中notify方法需要service 跨进程调用#xff0c;通知客户端播放消息 IMediaPlayerClient.aidl package com.example.demo; import com.example.demo.ParcelableParcel; interface IM… 2019独角兽企业重金招聘Python工程师标准 客户端进程需要实现其中notify方法需要service 跨进程调用通知客户端播放消息 IMediaPlayerClient.aidl package com.example.demo; import com.example.demo.ParcelableParcel; interface IMediaPlayerClient { void notify(int msg, int ext1, int ext2, in ParcelableParcel obj); } public class MediaPlayerClientBn extends IMediaPlayerClient.Stub implements IMediaDeathNotifier { // 其中重要的方法 public void init() { this.mLock new ReentrantLock(); this.mNotifyLock new ReentrantLock(); this.mSignal this.mLock.newCondition(); mPlayer null; mListener null; mCookie null; mStreamType 3 /* TODO AUDIO_STREAM_MUSIC */; mAudioAttributesParcel null; mCurrentPosition -1; mSeekPosition -1; mCurrentState MEDIA_PLAYER_IDLE; mPrepareSync false; mPrepareStatus MediaErrorsNum.NO_ERROR; mLoop false; mLeftVolume mRightVolume 1.0f; mVideoWidth mVideoHeight 0; mLockThreadId 0; mAudioSessionId 0; /* * TODO mAudioSessionId AudioSystem::newAudioUniqueId(); * AudioSystem::acquireAudioSessionId(mAudioSessionId, -1); */ mSendLevel 0; mRetransmitEndpointValid false; } int attachNewPlayer(IMediaPlayer player) { Log.i(LOG_TAG, attachNewPlayer); int err MediaErrorsNum.UNKNOWN_ERROR; IMediaPlayer p; { // scope for the lock mLock.lock(); if (( 0 (mCurrentState MEDIA_PLAYER_IDLE)) || (mCurrentState MEDIA_PLAYER_STATE_ERROR)) { Log.e(LOG_TAG, attachNewPlayer called in state mCurrentState); return MediaErrorsNum.INVALID_OPERATION; } clear_l(); p mPlayer; mPlayer player; Log.i(LOG_TAG, mPlayer is mPlayer.toString()); if (player ! null) { mCurrentState MEDIA_PLAYER_INITIALIZED; err MediaErrorsNum.NO_ERROR; } else { Log.e(LOG_TAG, Unable to create media player); } mLock.unlock(); } if (p ! null) { try { p.disconnect(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return err; } //获得getRemoteMediaPlayerServiceInstance创建IMediaPlayer并且使得 IMediaPlayer 和IMediaPlayerClient 实例一一对应互相引用。 并且用MediaDeathNotifier 通知service 的生命周期。 public int setDataSource(final IMediaHTTPService httpService, String url, final HashMapString, String headers) { mAudioSessionId ; int err MediaErrorsNum.BAD_VALUE; Log.i(LOG_TAG, setDataSource( url )); try { if (url ! null) { IMyMediaPlayerService service; /* service MediaDeathNotifier.getMediaPlayerService();*/ service MediaPlayer_Surface_iadl_MultThread_TestBase.getRemoteMediaPlayerServiceInstance(); if (service ! null) { IMediaPlayer player (service .create(this, mAudioSessionId)); if ((MediaErrorsNum.NO_ERROR ! doSetRetransmitEndpoint(player)) || (MediaErrorsNum.NO_ERROR ! player .setDataSource(httpService, url, null/* TODO */))) { player null; } err attachNewPlayer(player); } } } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } return err; } prepare public int prepare() { Log.i(LOG_TAG, prepare()); mLock.lock(); mLockThreadId (int) Thread.currentThread().getId(); if (mPrepareSync) { mLockThreadId 0; return MediaErrorsNum.EALREADY; } mPrepareSync true; int ret MediaErrorsNum.NO_ERROR; try { ret prepareAsync_l(); } catch (RemoteException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if (ret ! MediaErrorsNum.NO_ERROR) { mLockThreadId 0; return ret; } if (mPrepareSync) { try { mSignal.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // wait for prepare done mPrepareSync false; } Log.i(LOG_TAG, prepare complete - status mPrepareStatus); mLockThreadId 0; mLock.unlock(); return mPrepareStatus; } private int prepareAsync_l() throws RemoteException { if ((mPlayer ! null) (mCurrentState (MediaPlayerClientBn.MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED)) ! 0) { Log.i(LOG_TAG,mCurrentState is MEDIA_PLAYER_INITIALIZED or MEDIA_PLAYER_STOPPED); if (mAudioAttributesParcel ! null) { mPlayer.setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, ParcelableParcel.CREATOR .createFromParcel(mAudioAttributesParcel)); } else { mPlayer.setAudioStreamType(mStreamType); } mCurrentState MEDIA_PLAYER_PREPARING; return mPlayer.prepareAsync(); } Log.i(LOG_TAG, prepareAsync called in state mCurrentState); return MediaErrorsNum.INVALID_OPERATION; } // start play public int start() { Log.i(LOG_TAG, start()); int ret MediaErrorsNum.NO_ERROR; mLock.lock(); mLockThreadId Thread.currentThread().getId(); if ((mCurrentState MEDIA_PLAYER_STARTED) 1) { ret MediaErrorsNum.NO_ERROR; } else if ((mPlayer ! null) ((mCurrentState (MEDIA_PLAYER_PREPARED| MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED)) ! 0)) { try { mPlayer.setLooping(mLoop); mPlayer.setVolume(mLeftVolume, mRightVolume); mPlayer.setAuxEffectSendLevel(mSendLevel); mCurrentState MEDIA_PLAYER_STARTED; ret mPlayer.start(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (ret ! MediaErrorsNum.NO_ERROR) { mCurrentState MEDIA_PLAYER_STATE_ERROR; } else { if (mCurrentState MEDIA_PLAYER_PLAYBACK_COMPLETE) { Log.i(LOG_TAG, playback completed immediately following start()); } } } else { Log.e(LOG_TAG, start called in state mCurrentState); ret MediaErrorsNum.INVALID_OPERATION; } mLockThreadId 0; mLock.unlock(); return ret; } // 消息传递 Override public void notify(int msg, int ext1, int ext2, ParcelableParcel obj) throws RemoteException { // TODO Auto-generated method stub Log.i(LOG_TAG,message received msg%d, ext1%d, ext2%dmsg:ext1: ext2); boolean send true; boolean locked false; // TODO: In the future, we might be on the same thread if the app is // running in the same process as the media server. In that case, // this will deadlock. // // The threadId hack below works around this for the care of prepare, // seekTo and start within the same process. // FIXME: Remember, this is a hack, its not even a hack that is applied // consistently for all use-cases, this needs to be revisited. if (mLockThreadId ! Thread.currentThread().getId()) { mLock.lock(); locked true; } // Allows calls from JNI in idle state to notify errors if (!(msg MEDIA_ERROR mCurrentState MEDIA_PLAYER_IDLE) mPlayer null) { Log.i(LOG_TAG,notify(%d, %d, %d) callback on disconnected mediaplayer :msg:ext1:ext2); if (locked) mLock.unlock(); // release the lock when done. return; } switch (msg) { case MEDIA_NOP: // interface test message break; case MEDIA_PREPARED: Log.i(LOG_TAG,prepared); mCurrentState MEDIA_PLAYER_PREPARED; if (mPrepareSync) { Log.i(LOG_TAG,signal application thread); mPrepareSync false; mPrepareStatus MediaErrorsNum.NO_ERROR; mSignal.signal(); } break; case MEDIA_PLAYBACK_COMPLETE: Log.i(LOG_TAG,playback complete); if (mCurrentState MEDIA_PLAYER_IDLE) { Log.e(LOG_TAG,playback complete in idle state); } if (!mLoop) { mCurrentState MEDIA_PLAYER_PLAYBACK_COMPLETE; } break; case MEDIA_ERROR: // Always log errors. // ext1: Media framework error code. // ext2: Implementation dependant error code. Log.e(LOG_TAG,error (%d, %d):ext1: ext2); mCurrentState MEDIA_PLAYER_STATE_ERROR; if (mPrepareSync) { Log.i(LOG_TAG,signal application thread); mPrepareSync false; mPrepareStatus ext1; mSignal.signal(); send false; } break; case MEDIA_INFO: // ext1: Media framework error code. // ext2: Implementation dependant error code. if (ext1 ! MEDIA_INFO_VIDEO_TRACK_LAGGING) { Log.w(LOG_TAG,info/warning (%d, %d):ext1: ext2); } break; case MEDIA_SEEK_COMPLETE: Log.i(LOG_TAG,Received seek complete); if (mSeekPosition ! mCurrentPosition) { Log.i(LOG_TAG,Executing queued seekTo(%d) mSeekPosition); mSeekPosition -1; seekTo_l(mCurrentPosition); } else { Log.i(LOG_TAG,All seeks complete - return to regularly scheduled program); mCurrentPosition mSeekPosition -1; } break; case MEDIA_BUFFERING_UPDATE: Log.i(LOG_TAG,buffering %d ext1); break; case MEDIA_SET_VIDEO_SIZE: Log.i(LOG_TAG,New video size %d x %d:ext1: ext2); mVideoWidth ext1; mVideoHeight ext2; break; case MEDIA_TIMED_TEXT: Log.i(LOG_TAG,Received timed text message); break; case MEDIA_SUBTITLE_DATA: Log.i(LOG_TAG,Received subtitle data message); break; case MEDIA_META_DATA: Log.i(LOG_TAG,Received timed metadata message); break; default: Log.i(LOG_TAG,unrecognized message: (%d, %d, %d) : msg:ext1: ext2); break; } MediaPlayerListener listener mListener; if (locked) mLock.unlock(); // this prevents re-entrant calls into client code if ((listener ! null) send) { mNotifyLock.lock(); Log.i(LOG_TAG,callback application); listener.notify(msg, ext1, ext2, null obj?null:obj.getParcel()); mNotifyLock.unlock(); } } } IMyMediaPlayerService.aidl package com.example.demo; import com.example.demo.IMediaPlayer; import com.example.demo.IMediaPlayerClient; import com.example.demo.IOMX; import com.example.demo.ICrypto; import com.example.demo.IDrm; import com.example.demo.IHDCP; import com.example.demo.IMediaCodecList; import android.view.Surface; interface IMyMediaPlayerService { IMediaPlayer create(in IMediaPlayerClient client, int audioSessionId); IOMX getOMX(); ICrypto makeCrypto(); IDrm makeDrm(); IHDCP makeHDCP( boolean createEncryptionModule); IMediaCodecList getCodecList(); } public class MyMediaPlayerService extends Service { private static final String LOG_TAG MyMediaPlayerService.class.getName() ; public static void instantiate() { Log.i(LOG_TAG, instantiate call); } // For battery usage tracking purpose class BatteryUsageInfo { // how many streams are being played by one UID int refCount; // a temp variable to store the duration(ms) of audio codecs // when we start a audio codec, we minus the system time from // audioLastTime // when we pause it, we add the system time back to the audioLastTime // so after the pause, audioLastTime pause time - start time // if multiple audio streams are played (or recorded), then // audioLastTime // the total playing time of all the streams int audioLastTime; // when all the audio streams are being paused, we assign audioLastTime // to // this variable, so this value could be provided to the battery app // in the next pullBatteryData call int audioTotalTime; int videoLastTime; int videoTotalTime; }; HashMapInteger, BatteryUsageInfo mBatteryData null; private static final int SPEAKER 0; private static final int OTHER_AUDIO_DEVICE 1; private static final int SPEAKER_AND_OTHER 2; private static final int NUM_AUDIO_DEVICES 3; // ReentrantLock mLock new ReentrantLock(); VectorSoftReferenceMediaPlayerBn mClients new VectorSoftReferenceMediaPlayerBn(); int mNextConnId 0; AtomicInteger tmp new AtomicInteger(mNextConnId); IOMX mOMX; ICrypto mCrypto; SuppressLint(NewApi) private final IMyMediaPlayerService.Stub mBinder new IMyMediaPlayerService.Stub() {// 创建与IMediaPlayerClient相对的IMediaPlayer互粉并加入一个软引用向量管理对应关系。 Override public IMediaPlayer create(IMediaPlayerClient client, int audioSessionId) throws RemoteException { // TODO Auto-generated method stub long pid Binder.getCallingPid(); int connId tmp.getAndIncrement(); MediaPlayerBn c new MediaPlayerBn(MyMediaPlayerService.this, pid, connId, client, audioSessionId, Binder.getCallingUid()); Log.i(LOG_TAG, Create new client(connId) from pid pid, uid getCallingUid(), ); SoftReferenceMediaPlayerBn w new SoftReferenceMediaPlayerBn(c); { mLock.lock(); mClients.add(w); mLock.unlock(); } return c; } } } IMediaPlayer.aidl: package com.example.demo; import android.view.Surface; import com.example.demo.IMediaHTTPService; import com.example.demo.AudioPlaybackRate; import com.example.demo.AVSyncSettings; import com.example.demo.ParcelableParcel; import android.os.Messenger; interface IMediaPlayer { //void playLoadedVideo_iadl(in Surface surface); void disconnect(); int setDataSource(in IMediaHTTPService httpService, String url, String header /*HashMapString,String headers*/); //int setDataSource(int fd, long offset, long length); //int setDataSource(in IStreamSource source); //int setDataSource(in IDataSource source); int setVideoSurfaceTexture(in Surface surface); int prepareAsync(); int start(); int stop(); int pause(); int isPlaying(boolean state); int setPlaybackSettings(in AudioPlaybackRate rate); int getPlaybackSettings(in AudioPlaybackRate rate /* nonnull */); int setSyncSettings(in AVSyncSettings sync, float videoFpsHint); int getSyncSettings(in AVSyncSettings sync /* nonnull */, float videoFps /* nonnull */); int seekTo(int msec) ; int getCurrentPosition(int msec); int getDuration(int msec); int reset(); /*typedef enum { AUDIO_STREAM_DEFAULT -1, AUDIO_STREAM_MIN 0, AUDIO_STREAM_VOICE_CALL 0, AUDIO_STREAM_SYSTEM 1, AUDIO_STREAM_RING 2, AUDIO_STREAM_MUSIC 3, AUDIO_STREAM_ALARM 4, AUDIO_STREAM_NOTIFICATION 5, AUDIO_STREAM_BLUETOOTH_SCO 6, AUDIO_STREAM_ENFORCED_AUDIBLE 7, AUDIO_STREAM_DTMF 8, AUDIO_STREAM_TTS 9, AUDIO_STREAM_BOOT 10, AUDIO_STREAM_VIBSPK 11, AUDIO_STREAM_ACCESSIBILITY 12, AUDIO_STREAM_REROUTING 13, AUDIO_STREAM_PATCH 14, AUDIO_STREAM_PUBLIC_CNT AUDIO_STREAM_VIBSPK 1, AUDIO_STREAM_CNT AUDIO_STREAM_PATCH 1, } audio_stream_type_t;*/ int setAudioStreamType(/*audio_stream_type_t type*/int type); int setLooping(boolean loop) ; int setVolume(float leftVolume, float rightVolume) ; int setAuxEffectSendLevel(float level); int attachAuxEffect(int effectId) ; int setParameter(int key,in ParcelableParcel request); int getParameter(int key,in ParcelableParcel reply); int setRetransmitEndpoint0(String endpoint /*const struct sockaddr_in* endpoint*/); int getRetransmitEndpoint1(String endpoint /*struct sockaddr_in* endpoint*/); int setNextPlayer(in IMediaPlayer next); int setMetadataFilter(in ParcelableParcel filter); int getMetadata(boolean update_only, boolean apply_filter,in ParcelableParcel metadata); } package com.example.demo; import java.io.IOException; import java.lang.ref.SoftReference; import java.util.concurrent.locks.ReentrantLock; import android.annotation.SuppressLint; import android.media.MediaPlayer; import android.media.MediaPlayer.OnBufferingUpdateListener; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnInfoListener; import android.media.MediaPlayer.OnPreparedListener; import android.media.MediaPlayer.OnSeekCompleteListener; import android.media.MediaPlayer.OnVideoSizeChangedListener; import android.os.Binder; import android.os.Parcel; import android.os.RemoteException; import android.util.Log; import android.view.Surface; SuppressLint(NewApi) public class MediaPlayerBn extends IMediaPlayer.Stub { private static final String LOG_TAG MediaPlayerBn.class.getName(); private static final int NO_INIT 0; private static final int AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 64/* TODO */; class audio_attributes_t { /* * TODO audio_content_type_t content_type; audio_usage_t usage; * audio_source_t source; audio_flags_mask_t flags; char * tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE]; UTF8 */ }; ReentrantLock mLock; /* MediaPlayerBase mPlayer; */ MediaPlayer mPlayer; MyMediaPlayerService mService; IMediaPlayerClient mClient; AudioOutput mAudioOutput; int mPid; int mStatus; boolean mLoop; int mConnId; int mAudioSessionId; audio_attributes_t mAudioAttributes; long mUID; Surface mConnectedWindow; Binder mConnectedWindowBinder; String mRetransmitEndpoint; boolean mRetransmitEndpointValid; MediaPlayerBn mNextClient; // Metadata filters. /* media::Metadata::Filter */Object mMetadataAllow; // protected by mLock /* media::Metadata::Filter */Object mMetadataDrop; // protected by mLock // Metadata updated. For each MEDIA_INFO_METADATA_UPDATE // notification we try to update mMetadataUpdated which is a // set: no duplicate. // getMetadata clears this set. /* media::Metadata::Filter */Object mMetadataUpdated; // protected by mLock /* * TODO #if CALLBACK_ANTAGONIZER Antagonizer* mAntagonizer; #endif */ Object mAntagonizer; OnErrorListener mErrorListener new MediaPlayer.OnErrorListener() { Override public boolean onError(MediaPlayer mp, int what, int extra) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 100, what, extra, null); return false; } }; OnInfoListener mInfoListener new MediaPlayer.OnInfoListener() { Override public boolean onInfo(MediaPlayer mp, int what, int extra) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 200, what, extra, null); return false; } }; OnBufferingUpdateListener mBufferingUpdateListener new MediaPlayer.OnBufferingUpdateListener() { Override public void onBufferingUpdate(MediaPlayer mp, int percent) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 3, 3, percent, null); } }; OnCompletionListener mCompletionListener new MediaPlayer.OnCompletionListener() { Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 2, 2, 0, null); } }; OnPreparedListener mPreparedListener new MediaPlayer.OnPreparedListener() { Override public void onPrepared(MediaPlayer mp) { // TODO Auto-generated method stub Log.i(LOG_TAG,mPreparedListener.onPrepared() ); MediaPlayerBn.this.notify(MediaPlayerBn.this, 1, 1, 0, null); } }; OnSeekCompleteListener mSeekCompleteListener new MediaPlayer.OnSeekCompleteListener() { Override public void onSeekComplete(MediaPlayer mp) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 4, 4, 0, null); } }; OnVideoSizeChangedListener mVideoSizeChangedListener new MediaPlayer.OnVideoSizeChangedListener() { Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { // TODO Auto-generated method stub MediaPlayerBn.this.notify(MediaPlayerBn.this, 5, 5, 0, null); } }; public MediaPlayerBn(MyMediaPlayerService service, long pid, int connId, IMediaPlayerClient client, int audioSessionId, long uid) { Log.i(LOG_TAG, Client(%d) constructor connId); mPid (int) pid; mConnId connId; mService service; mClient client; mLoop false; mStatus NO_INIT; mAudioSessionId audioSessionId; mUID uid; mRetransmitEndpointValid false; mAudioAttributes null; mLock new ReentrantLock(); Log.i(LOG_TAG, create Antagonizer is null); mAntagonizer null; mPlayer new MediaPlayer(); mPlayer.setOnErrorListener(mErrorListener); mPlayer.setOnInfoListener(mInfoListener); mPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); mPlayer.setOnCompletionListener(mCompletionListener); mPlayer.setOnPreparedListener(mPreparedListener); mPlayer.setOnSeekCompleteListener(mSeekCompleteListener); mPlayer.setOnVideoSizeChangedListener(mVideoSizeChangedListener); } public void desdroy() { Log.i(LOG_TAG, Client(%d) destructor pid %d mConnId : mPid); mAudioOutput null; SoftReferenceMediaPlayerBn client new SoftReferenceMediaPlayerBn( this); try { disconnect(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } // destory 的时候删除引用 mService.removeClient(client); if (mAudioAttributes ! null) { /* TODO free(mAudioAttributes); */ mAudioAttributes null; } } Override public void disconnect() throws RemoteException { // TODO Auto-generated method stub Log.i(LOG_TAG, disconnect(%d) from pid %d mConnId : mPid); // grab local reference and clear main reference to prevent future // access to object MediaPlayer p; { mLock.lock(); p mPlayer; mLock.unlock(); } mPlayer null; // clear the notification to prevent callbacks to dead client // and reset the player. We assume the player will serialize // access to itself if necessary. if (p ! null) { /* TODO p.setNotifyCallback(0, 0); */ p.reset(); } /* TODOdisconnectNativeWindow(); */ /* TODO IPCThreadState::self()-flushCommands(); */ } Override public int setDataSource(IMediaHTTPService httpService, String url, String header) throws RemoteException { // TODO Auto-generated method stub Log.i(LOG_TAG, setDataSource(%s) url); try { mPlayer.setDataSource(url); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 0; } } 客户端多实例调用 /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.demo; import java.io.IOException; import java.util.logging.Logger; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.media.MediaPlayer; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; SuppressLint(NewApi) public class MediaPlayer_Surface_iadl_MultThread_TestBase extends Activity { private static final String LOG_TAG MediaPlayer_Surface_iadl_MultThread_TestBase.class .getName() liyl add; protected static final int SLEEP_TIME 1000; protected static final int LONG_SLEEP_TIME 6000; protected static final int STREAM_RETRIES 1; protected static boolean sUseScaleToFitMode false; /* * protected Monitor mOnVideoSizeChangedCalled new Monitor(); protected * Monitor mOnVideoRenderingStartCalled new Monitor(); protected Monitor * mOnBufferingUpdateCalled new Monitor(); protected Monitor * mOnPrepareCalled new Monitor(); protected Monitor mOnSeekCompleteCalled * new Monitor(); protected Monitor mOnCompletionCalled new Monitor(); * protected Monitor mOnInfoCalled new Monitor(); protected Monitor * mOnErrorCalled new Monitor(); */ protected SurfaceHolder mSurfaceHolder1 null; protected SurfaceHolder mSurfaceHolder2 null; private SurfaceHolder mHolder1; private SurfaceHolder mHolder2; protected MediaPlayer_Surface_iadl_MultThread_TestBase mActivity; private boolean mIsRemoteBound false; private static IMyMediaPlayerService mRemoteService null; private MediaPlayerClientWrapper mPlayerWrapper1; private MediaPlayerClientWrapper mPlayerWrapper2; public static IMyMediaPlayerService getRemoteMediaPlayerServiceInstance() { if(mRemoteService null) { Log.e(LOG_TAG,not should be here!!!); return mRemoteService; } return mRemoteService; } protected class MediaPlayerClientWrapper implements MediaPlayerListener { public MediaPlayerClientWrapper() { super(); this.mPlayerClient new MediaPlayerClientBn(); } private MediaPlayerClientBn mPlayerClient; public MediaPlayerClientBn getmPlayerClient() { return mPlayerClient; } Override public void notify(int msg, int ext1, int ext2, Parcel obj) { // TODO Auto-generated method stub Log.e(LOG_TAG,msg msg ext1 ext1 ext2 ext2 obj obj); if(msg 1/*MEDIA_PREPARED*/) { mPlayerClient.start(); } } public void desdroy() { this.mPlayerClient null; } } private ServiceConnection mRemoteConnection new ServiceConnection() { Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mRemoteService IMyMediaPlayerService.Stub.asInterface(service); Log.i(LOG_TAG,mRemoteService null is (mRemoteService null)); } Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mRemoteService null; } }; public MediaPlayer_Surface_iadl_MultThread_TestBase() { super(); } protected void setUp() { mSurfaceHolder1 getSurfaceHolder1(); mSurfaceHolder2 getSurfaceHolder2(); if (!mIsRemoteBound) { Intent mIntent new Intent(); mIntent.setAction(com.example.demo.IMyMediaPlayerService);//你定义的service的action mIntent.setPackage(getPackageName());//这里你需要设置你应用的包名 //startService(mIntent); bindService(mIntent, mRemoteConnection, Context.BIND_AUTO_CREATE); mIsRemoteBound !mIsRemoteBound; } mPlayerWrapper1 new MediaPlayerClientWrapper(); mPlayerWrapper2 new MediaPlayerClientWrapper(); mPlayerWrapper1.getmPlayerClient().setListener(mPlayerWrapper1); mPlayerWrapper2.getmPlayerClient().setListener(mPlayerWrapper2); } public SurfaceHolder getSurfaceHolder1() { return mHolder1; } public SurfaceHolder getSurfaceHolder2() { return mHolder2; } Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.mediaplayermultsurface); mActivity this; SurfaceView surfaceV1 (SurfaceView) findViewById(R.id.surface1); mHolder1 surfaceV1.getHolder(); SurfaceView surfaceV2 (SurfaceView) findViewById(R.id.surface2); mHolder2 surfaceV2.getHolder(); setUp(); } Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); tearDown(); } Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); if(mRemoteService null) { Log.w(LOG_TAG,mRemoteService is null); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } mSurfaceHolder1.addCallback(new SurfaceHolder.Callback() { Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub mSurfaceHolder1 arg0; } Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub try { mPlayerWrapper1.getmPlayerClient().setDataSource(null,http://10.154.250.32:8081/share/mediatest/normal/hls/1080p/desc.m3u8, null); mPlayerWrapper1.getmPlayerClient().setVideoSurfaceTexture(mActivity.getSurfaceHolder1() .getSurface()); mPlayerWrapper1.getmPlayerClient().prepare(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub mSurfaceHolder1 null; } }); mSurfaceHolder2.addCallback(new SurfaceHolder.Callback() { Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub mSurfaceHolder2 arg0; } Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub try { mPlayerWrapper2.getmPlayerClient().setDataSource(null,http://10.154.250.32:8081/share/mediatest/normal/hls/1080p/desc.m3u8, null); mPlayerWrapper2.getmPlayerClient().setVideoSurfaceTexture(mActivity.getSurfaceHolder2() .getSurface()); mPlayerWrapper2.getmPlayerClient().prepare(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub mSurfaceHolder2 null; } }); Log.w(LOG_TAG,Sleep 5 s); /* try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ } private void clear() { mPlayerWrapper1.desdroy(); mPlayerWrapper2.desdroy(); } protected void tearDown() { clear(); if (!mIsRemoteBound) { unbindService(mRemoteConnection); mIsRemoteBound !mIsRemoteBound; } } // // } 转载于:https://my.oschina.net/u/269082/blog/647380