導航:首頁 > 操作系統 > androidmediaplay

androidmediaplay

發布時間:2022-09-07 00:03:01

⑴ 安卓開發中,使用surfaceView和Mediaplay播發視頻為什麼會失敗,模擬器上播放不了求大神解救,錯在哪

模擬器不能使用播放不能代表什麼,也可以是模擬器的配置問題,不一定就是代碼的問題,你先找一個手機試一下,手機可以運行那就沒什麼問題,如果不行再去定位問題,如果這樣一味調試下去的話,只能是浪費時間

android soundpool能不能在除了activity之外的類中使用

在開發android軟體中,經常需要播放多媒體音頻文件,通常會採用MediaPlayer類來執行此類操作。但MediaPlayer類佔用的資源比較多,對於游戲等應用而言,會帶來性能上的降低。在Android中,專門提供了SoundPool類來執行此類音頻播放,SoundPool類佔用的CPU資源較少、反應較快。
SoundPool使用MediaPlaybackService將音頻流解碼為16位的PCM單聲道或者立體聲流。這有利於減小解碼造成的應用延遲。
SoundPool的常用方法包括:
load() //載入音頻文件
pause() //暫停
play() //播放
resume() //恢復
setLoop() //設置循環模式
setOnLoadCompleteListener() //設置監聽器
setVolume() //設置音量
setRate() //設置播放速率
SoundPool類和其他音頻播放類相比,可以自行設置音頻播放時的品質、音量、播放速率等。並且它可以管理多個音頻流,每個流均擁有自己獨立的ID,對單個音頻流的管理均是通過其ID來進行的。SoundPool類適用的場景包括應用程序中的聲效(按鍵提示音、消息等)、游戲中密集而短暫的聲音(如多個飛船同時爆炸)。
SoundPool類的使用方法如下:
代碼10-5 SoundPool播放音頻的一般過程

int srcQuality=100;
int waitMsec=1000;
float leftVolume=SILENT;
float rightVolume=LOUD;
int priority=1;
int loop=0;
float rate=1f;
SoundPool mSoundPool=new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
int sampleId1=mSoundPool.load(mContext, SOUND_A, PRIORITY);
int streamID=mSoundPool.play(sampleID, leftVolume, rightVolume, priority, loop, rate);
……

⑶ 怎樣監聽android的mediaplay播放網路音樂時,每一次的緩沖以及每一次緩沖結束

isplaying和!isplaying不行嗎?

⑷ android.media.AsyncPlayer這個類應該怎麼用

代碼結構:

Open Core 的代碼在Android 代碼的 External/Opencore 目錄中 。這個目錄是OpenCore
的根目錄,其中包含的子目錄如下所示 :

android :這裡面是一個上層的庫,它實現了一個為Android 使用的音視頻採集,播放的介面,和DRM 數字版權管理的介面實現。

baselibs :包含數據結構和線程安全等內容的底層庫

codecs_v2 :音視頻的編解碼器,基於 OpenMAX 實現

engines :核心部分 ,多媒體 引擎的實現

extern_libs_v2 :包含了 khronos 的 OpenMAX 的頭文件

fileformats :文件格式的解析( parser )工具

nodes :提供一些PVMF 的NODE ,主要是編解碼和文件解析方面的。

oscl :操作系統兼容庫

pvmi : 輸入輸出控制的抽象介面

protocols :主要是與網路相關的 RTSP 、 RTP 、 HTTP 等協議 的相關內容

pvcommon : pvcommon 庫文件的 Android.mk 文件,沒有源文件。

pvplayer : pvplayer 庫文件的 Android.mk 文件,沒有源文件。

pvauthor : pvauthor 庫文件的 Android.mk 文件,沒有源文件。

tools_v2 :編譯工具以及一些可注冊的模塊。

本文主要介紹Android MediaPlayer的架構,主要由OpenCore 里的PV Player來實現的。

1.概述

Android的MediaPlayer包含了Audio和Video的播放功能,Music和Video兩個應用程序都是調用MediaPlayer實現的。

代碼主要分布在以下的目錄中:

java程序的路徑:

packages/apps/Music/src/com/android/music/

JAVA類的路徑:

frameworks/base/media/java/android/media/MediaPlayer.java

JAVA本地調用部分(JNI):

frameworks/base/media/jni/android_media_MediaPlayer.cpp

編譯為 libmedia_jni.so

頭文件:

frameworks/base/include/media/

多媒體庫:

frameworks/base/media/libmedia/

編譯為 libmedia.so

多媒體服務:

frameworks/base/media/libmediaplayerservice/

編譯為 libmediaplayerservice.so

具體實現:

external/opencore/

編譯為 libopencoreplayer.so

libopencoreplayer.so是主要的實現部分,其他的庫基本上都是在其上建立的封裝和為建立進程間通訊的機制。

2.框架


運行的時候,大致可以分成Client和Server兩個部分,分別在兩個進程中運行,使用Binder機制實現IPC通訊。從框架結構上來看,IMediaPlayerService.h、IMediaPlayerClient.h和MediaPlayer.h三個類定義了MeidaPlayer的介面和架構,MediaPlayerService.cpp和mediaplayer.cpp兩個文件用於MeidaPlayer架構的實現,MeidaPlayer的具體功能在PVPlayer(庫libopencoreplayer.so)中的實現。

2.1 IMediaPlayerClient.h

描述一個MediaPlayer客戶端的介面

class IMediaPlayerClient: public IInterface

{

public:

DECLARE_META_INTERFACE(MediaPlayerClient);

virtual void notify(int msg, int ext1, int ext2) = 0;

};

class BnMediaPlayerClient: public BnInterface

{

public:

virtual status_t onTransact( uint32_t code,

const Parcel& data,

Parcel* reply,

uint32_t flags = 0);

};

在定義中,IMediaPlayerClient類繼承IInterface,並定義了一個MediaPlayer客戶端的介面,BnMediaPlayerClient繼承了BnInterface,這是為基於Android的基礎類Binder機制實現在進程通訊而構建的。事實上,根據BnInterface類模版的定義,BnInterface類相當於雙繼承了BnInterface和ImediaPlayerClient,這是Android一種常用的定義方式。

2.2 mediaplayer.h

對外的介面類,它最主要是定義了一個MediaPlayer類:

class MediaPlayer : public BnMediaPlayerClient

{

public:

MediaPlayer();

~MediaPlayer();

void onFirstRef();

void disconnect();

status_t setDataSource(const char *url);

status_t setDataSource(int fd, int64_t offset, int64_t length);

status_t setVideoSurface(const sp& surface);

status_t setListener(const sp& listener);

status_t prepare();

status_t prepareAsync();

status_t start();

status_t stop();

status_t pause();

bool isPlaying();

status_t getVideoWidth(int *w);

status_t getVideoHeight(int *h);

status_t seekTo(int msec);

status_t getCurrentPosition(int *msec);

status_t getDuration(int *msec);

status_t reset();

status_t setAudioStreamType(int type);

status_t setLooping(int loop);

status_t setVolume(float leftVolume, float rightVolume);

void notify(int msg, int ext1, int ext2);

static sp decode(const char* url, uint32_t *pSampleRate, int*
pNumChannels);

static sp decode(int fd, int64_t offset, int64_t length, uint32_t
*pSampleRate, int* pNumChannels);

//……

}

從介面中可以看出MediaPlayer類剛好實現了一個MediaPlayer的基本操作,例如播放(start)、停止(stop)、暫停(pause)等。

另外的一個類DeathNotifier在MediaPlayer類中定義,它繼承了IBinder類中的DeathRecipient類:

class DeathNotifier: public IBinder:: DeathRecipient

{

public:

DeathNotifier() {}

virtual ~DeathNotifier();

virtual void binderDied(const wp& who);

};

事實上,MediaPlayer類正是間接地繼承了IBinder,而MediaPlayer:: DeathNotifier類繼承了IBinder::
DeathRecipient,這都是為了實現進程間通訊而構建的。

2.3 IMediaPlayer.h

主要的的內容是一個實現MediaPlayer功能的介面:

class IMediaPlayer: public IInterface

{

public:

DECLARE_META_INTERFACE(MediaPlayer);

virtual void disconnect() = 0;

virtual status_t setVideoSurface(const sp& surface) = 0;

virtual status_t prepareAsync() = 0;

virtual status_t start() = 0;

virtual status_t stop() = 0;

virtual status_t pause() = 0;

virtual status_t isPlaying(bool* state) = 0;

virtual status_t getVideoSize(int* w, int* h) = 0;

virtual status_t seekTo(int msec) = 0;

virtual status_t getCurrentPosition(int* msec) = 0;

virtual status_t getDuration(int* msec) = 0;

virtual status_t reset() = 0;

virtual status_t setAudioStreamType(int type) = 0;

virtual status_t setLooping(int loop) = 0;

virtual status_t setVolume(float leftVolume, float rightVolume) = 0;

};

class BnMediaPlayer: public BnInterface

{

public:

virtual status_t onTransact( uint32_t code,

const Parcel& data,

Parcel* reply,

uint32_t flags = 0);

};

在IMediaPlayer類中,主要定義MediaPlayer的功能介面,這個類必須被繼承才能夠使用。值得注意的是,這些介面和MediaPlayer類的介面有些類似,但是它們並沒有直接的關系。事實上,在MediaPlayer類的各種實現中,一般都會通過調用IMediaPlayer類的實現類來完成。

2.4 頭文件IMediaPlayerService.h

描述一個MediaPlayer的服務,定義方式如下所示:

class IMediaPlayerService: public IInterface

{

public:

DECLARE_META_INTERFACE(MediaPlayerService);

virtual sp create(pid_t pid, const
sp& client, const char* url) = 0;

virtual sp create(pid_t pid, const
sp& client, int fd, int64_t offset, int64_t length) =
0;

virtual sp decode(const char* url, uint32_t *pSampleRate, int*
pNumChannels) = 0;

virtual sp decode(int fd, int64_t offset, int64_t length, uint32_t
*pSampleRate, int* pNumChannels) = 0;

};

class BnMediaPlayerService: public BnInterface

{

public:

virtual status_t onTransact( uint32_t code,

const Parcel& data,

Parcel* reply,

uint32_t flags = 0);

};

由於有純虛函數,IMediaPlayerService
以及BnMediaPlayerService必須被繼承實現才能夠使用,在IMediaPlayerService定義的create和decode等介面,事實上是必須被繼承者實現的內容。注意,create的返回值的類型是sp,這個IMediaPlayer正是提供實現功能的介面。

3 實現

3.1 App

在packages/apps/Music/src/com/android/music/里的MediaPlaybackService.java文件中,包含了對MediaPlayer的調用。

在MediaPlaybackService.java中包含對包的引用:

import android.media.MediaPlayer;

在MediaPlaybackService類的內部,定義了MultiPlayer類:

private class MultiPlayer {

private MediaPlayer mMediaPlayer = new MediaPlayer();

}

MultiPlayer類中使用了MediaPlayer類,其中有一些對這個MediaPlayer的調用,調用的過程如下所示:

mMediaPlayer.reset();

mMediaPlayer.setDataSource(path);

mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

reset,setDataSource和setAudioStreamType等介面就是通過JAVA本地調用(JNI)來實現的。

3.2 Jni

在frameworks/base/media/jni/android_media_MediaPlayer.cpp中實現,其中android_media_MediaPlayer_reset函數的實現如下所示:

static void android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)

{

sp mp = getMediaPlayer(env, thiz);

if (mp == NULL ) {

jniThrowException(env, "java/lang/IllegalStateException", NULL);

return;

}

process_media_player_call( env, thiz, mp->reset(), NULL, NULL );

}

先獲取一個MediaPlayer指針,通過對它的調用來實現實際的功能。

register_android_media_MediaPlayer用於將gMethods注冊為的類"android/media/MediaPlayer",其實現如下所示。

static int register_android_media_MediaPlayer(JNIEnv *env)

{

jclass clazz;

clazz = env->FindClass("android/media/MediaPlayer");

// ......

return AndroidRuntime::registerNativeMethods(env,
"android/media/MediaPlayer", gMethods, NELEM(gMethods));

}

"android/media/MediaPlayer"對應JAVA的類android.media.MediaPlayer。

3.3 libmedia.so

frameworks/base/media/libmedia/mediaplayer.cpp文件實現mediaplayer.h提供的介面,其中一個重要的片段如下所示:

const sp& MediaPlayer::getMediaPlayerService()

{

Mutex::Autolock _l(mServiceLock);

if (mMediaPlayerService.get() == 0) {

sp sm = defaultServiceManager();

sp binder;

do {

binder = sm->getService(String16("media.player"));

if (binder != 0)

break;

LOGW("MediaPlayerService not published, waiting...");

usleep(500000); // 0.5 s

} while(true);

if (mDeathNotifier == NULL) {

mDeathNotifier = new DeathNotifier();

}

binder->linkToDeath(mDeathNotifier);

mMediaPlayerService = interface_cast(binder);

}

LOGE_IF(mMediaPlayerService==0, "no MediaPlayerService!?");

return mMediaPlayerService;

}

其中最重要的一點是binder =
sm->getService(String16("media.player"));這個調用用來得到一個名稱為"media.player"的服務,這個調用返回值的類型為IBinder,根據實現將其轉換成類型IMediaPlayerService使用。

一個具體的函數setDataSource如下所示:

status_t MediaPlayer::setDataSource(const char *url)

{

LOGV("setDataSource(%s)", url);

status_t err = UNKNOWN_ERROR;

if (url != NULL) {

const sp& service(getMediaPlayerService());

if (service != 0) {

sp player(service->create(getpid(), this, url));

err = setDataSource(player);

}

}

return err;

}

⑸ android里音樂沒播放怎麼也調用setoncompletionlistener

1.對於控制研究媒體播放器,通過本地服務打,不如送媒體播放器參考其他類一樣CarefulMediaPlayer(MP,這一點);你在處理此類播放器的屬性。我認為它幫助你。 謝謝
2.我為這個問題掙扎,最後我得到了它的工作班以下。這個想法是一個線程與活套,剩下活著,並處理所有的MediaPlayer的邏輯。 我只退出尺蠖和清理線程,如果服務接收到的明確

{
privatestaticPowerManager.WakeLockwakeLock;
privatestaticfinalStringTAG="PlayService";
privatestaticStringLOCK_NAME=TAG;
publicstaticfinalStringEXTRA_FILE="file";
publicstaticfinalStringACTION_PLAY="play";
_STOP="stop";
publicstaticfinalintMSG_START=1;
publicstaticfinalintMSG_STOP=2;
publicPlayService(Stringname){
super(name);
}
publicPlayService(){
super("PlayService");
}
@Override
publicvoidonCreate(){
super.onCreate();
}
@Override
protectedvoidonHandleIntent(Intentintent){
Messagemsg=newMessage();
if(ACTION_PLAY.equalsIgnoreCase(intent.getAction())){
StringfileName=intent.getExtras().getString(EXTRA_FILE);
msg.what=MSG_START;
msg.obj=fileName;
}elseif(ACTION_STOP.equalsIgnoreCase(intent.getAction())){
msg.what=MSG_STOP;
}
try{
PlayMediaThread.getInstance(this).sendMessage(msg);
}catch(InterruptedExceptione){
Log.e(TAG,e.getMessage());
}
}
publicstaticPowerManager.WakeLockacquireLock(Contextcontext){
if(wakeLock==null||!wakeLock.isHeld()){
PowerManagerpowerManager=(PowerManager)context
.getSystemService(Context.POWER_SERVICE);
wakeLock=powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME);
wakeLock.setReferenceCounted(true);
wakeLock.acquire();
}
returnwakeLock;
}
publicstaticvoidreleaseLock(Contextcontext){
if(wakeLock!=null&&wakeLock.isHeld()){
wakeLock.release();
}
}
}
,
OnErrorListener,OnPreparedListener{
=newSemaphore(0);
privatestaticHandlerhandler;
privatestaticLoopermyLooper;
privatestaticContextcontext;
;
;
;
privatestaticfinalStringTAG="PlayMediaThread";
privatePlayMediaThread(Contextcontext)throwsInterruptedException{
super(TAG);
PlayMediaThread.context=context;
start();
//
//instance
semaphore.acquire();
}
(Contextcontext)
throwsInterruptedException{
if(instance==null){
instance=newPlayMediaThread(context);
}
PlayMediaThread.context=context;
returninstance;
}
publicvoidsendMessage(Messagemsg){
handler.sendMessage(msg);
}
publicvoidquitLooper(){
try{
if(myLooper!=null){
myLooper.quit();
Log.i(TAG,"Afterquit");
}
}catch(Exceptionex){
Log.e(TAG,ex.getMessage());
}
}
@Override
publicvoidrun(){
Looper.prepare();
myLooper=Looper.myLooper();
handler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
if(msg.what==PlayService.MSG_START){
startPlayer((String)msg.obj);
}elseif(msg.what==PlayService.MSG_STOP){
//.e.user
//explicitlyclickedstop,Iquitthelooperand
//cleanthethread
stopPlayer(true);
}
}
};
semaphore.release();
Log.i(TAG,"BeforeLoop");
Looper.loop();
}
privatevoidstopPlayer(booleanclean){
if(player!=null){
if(player.isPlaying()){
player.stop();
}
player.release();
player=null;
}
if(clean){
PlayService.releaseLock(context);
quitLooper();
instance=null;
}
}
privatevoidstartPlayer(StringfileName){
if(player!=null&&player.isPlaying()&&currentFileName!=null
&&currentFileName.equalsIgnoreCase(fileName)){
return;
}
currentFileName=fileName;
stopPlayer(false);
player=newMediaPlayer();
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
player.setOnPreparedListener(this);
try{
player.setDataSource(context,Uri.parse(currentFileName));
player.prepare();
player.start();
PlayService.acquireLock(context);
}catch(Exceptione){
Log.e(TAG,e.getMessage());
}
}
@Override
publicbooleanonError(MediaPlayermp,intarg1,intarg2){
Log.e(TAG,"onError");
stopPlayer(true);
returnfalse;
}
@Override
publicvoidonCompletion(MediaPlayermp){
Log.d(TAG,"onCompletion");
//
stopPlayer(true);
}
@Override
publicvoidonPrepared(MediaPlayermp){
Log.d(TAG,"onPrepared");
}
}

⑹ android mediaplay 怎麼播放 rtsp /http 流媒體

但是網路電台的連接就是沒有擴展名的,在PC 上的media play 都可以播放的

⑺ android MediaPlayer setDataSource( String path )報錯

這是java的異常處理;這行代碼會產生異常,而在這里你沒有對異常處理,所以系統提示你「Unhandled exception」;解決方法如下:

第一種:使用try-catch捕獲該異常:
try{
ar.set~~~~~~~~~~~~~~;
}catch(Exception e){
e.printStackTrace();
}
第二種:在方法定義時 throws 該異常 public void play throws Exception(){。。。}

閱讀全文

與androidmediaplay相關的資料

熱點內容
python拼音轉換文字 瀏覽:562
動畫遺傳演算法 瀏覽:63
php如何解析xml文件 瀏覽:702
如何改變appstore的語言 瀏覽:462
javahtmlxml 瀏覽:34
單片機啟動文件 瀏覽:811
橙app如何開啟聊天 瀏覽:899
訪問伺服器公網地址 瀏覽:666
pdf列印底色去掉 瀏覽:463
java快遞介面 瀏覽:397
哪個app可以教新爸爸 瀏覽:210
如何查看伺服器系統版本信息 瀏覽:524
成都市土地出讓金演算法 瀏覽:703
鋼筋加密標記 瀏覽:578
ps中擴展功能在文件夾的什麼位置 瀏覽:905
雙極壓縮機為什麼要先高壓 瀏覽:529
蘋果手機伺服器填什麼 瀏覽:833
android移動動畫效果 瀏覽:693
電子和伺服器是什麼意思 瀏覽:694
phpurl中文亂碼問題 瀏覽:894