A. 請教android平台的RTSP協議和音視頻解碼器
接調用Mediaplayer就可以了,底層使用OPENCORE或者STAGEFRIGHT實現的
B. android VideoView 支持rtsp 的mp4格式嗎
Android 中的VideoView支持MP4格式的視頻。通過VideoView播放視頻的步驟:
1、在界面布局文件中定義VideoView組件,或在程序中創建VideoView組件
2、調用VideoView的如下兩個方法來載入指定的視頻,setVidePath(String path):載入path文件代表的視頻;setVideoURI(Uri uri):載入uri所對應的視頻。
3、調用VideoView的start()、stop()、psuse()方法來控制視頻的播放。
VideoView通過與MediaController類結合使用,開發者可以不用自己控制播放與暫停。
C. android怎麼播放rtsp實時網路串流代碼
android播放rtsp實時網路串流核心代碼如下:
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.VideoView;
public class rtspActivity extends Activity {
/** Called when the activity is first created. */
Button playButton ;
VideoView videoView ;
EditText rtspUrl ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rtspUrl = (EditText)this.findViewById(R.id.url);
playButton = (Button)this.findViewById(R.id.start_play); playButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
PlayRtspStream(rtspUrl.getEditableText().toString()); } });
videoView = (VideoView)this.findViewById(R.id.rtsp_player); }
//play rtsp stream
private void PlayRtspStream(String rtspUrl){
videoView.setVideoURI(Uri.parse(rtspUrl));
videoView.requestFocus();
videoView.start();
}
}
D. ijkPLayer 0.8.8播放rtsp(android),編譯出來的庫需要在真機上調試嗎
編譯環境是:
virtualbox下的ubuntu
jdk-8u112-linux-x64 .tar.gz
android-ndk-r13-linux-x86_64.zip
android-sdk_r24.4.1-linux.tgz
配置好這些後安裝: install homebrew, git, yasm
搭建好環境後就可以編譯了,開始我編譯出了0.8.4版本,發現播放不了rtsp,播放就是黑屏,後來發現有人說新版本有這個問題,退回到舊版本就沒有問題了,於是我使用了K0.7.6
E. 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;
}
F. android 怎麼播放rtsp流
package com.video.rtsp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.VideoView;
public class rtspActivity extends Activity {
/** Called when the activity is first created. */
Button playButton ;
VideoView videoView ;
EditText rtspUrl ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rtspUrl = (EditText)this.findViewById(R.id.url);
playButton = (Button)this.findViewById(R.id.start_play);
playButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
PlayRtspStream(rtspUrl.getEditableText().toString());
}
});
videoView = (VideoView)this.findViewById(R.id.rtsp_player);
}
//play rtsp stream
private void PlayRtspStream(String rtspUrl){
videoView.setVideoURI(Uri.parse(rtspUrl));
videoView.requestFocus();
videoView.start();
}
}
更多請關注扣丁學堂。
G. Android MediaRecorder 採集AAC的RTP打包。
1.不懂這個
2、3.RTP封裝AAC的時候把AAC數據的頭去掉,參照rfc3640的mpeg4的audio部分裡面有例子,RTP的payload(負載)格式網上有的是,我不知道你是什麼情況,我的情況是實現aac的rtsp實時流,然後用vlc播放,主要的就是SDP里的profile-level-id,config等描述的填寫,封包什麼的rfc里有介紹。
我也是新手,前些日子為了搞這個花了好長時間,有時間看一下rfc3640,希望能對你有所幫助
H. android 怎麼播放rtsp流
package com.video.rtsp;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.VideoView;
public class rtspActivity extends Activity {
/** Called when the activity is first created. */
Button playButton ;
VideoView videoView ;
EditText rtspUrl ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rtspUrl = (EditText)this.findViewById(R.id.url);
playButton = (Button)this.findViewById(R.id.start_play);
playButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
PlayRtspStream(rtspUrl.getEditableText().toString());
}
});
videoView = (VideoView)this.findViewById(R.id.rtsp_player);
}
//play rtsp stream
private void PlayRtspStream(String rtspUrl){
videoView.setVideoURI(Uri.parse(rtspUrl));
videoView.requestFocus();
videoView.start();
}
}
I. android如何通過rtsp查看網路攝像頭
rtsp視頻直播流在android上可以直接播放...但是要注意:要rtsp的幀數不要太高,不然解碼解不動...
J. 請教大神,android video view播放rtsp格式實時視頻,有10秒的延遲,怎麼能設
android播放rtsp實時網路串流核心代碼如下:
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.VideoView;
public class rtspActivity extends Activity {
/** Called when the activity is first created. */
Button playButton ;
VideoView videoView ;
EditText rtspUrl ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rtspUrl = (EditText)this.findViewById(R.id.url);
playButton = (Button)this.findViewById(R.id.start_play); playButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
PlayRtspStream(rtspUrl.getEditableText().toString()); } });
videoView = (VideoView)this.findViewById(R.id.rtsp_player); }
//play rtsp stream
private void PlayRtspStream(String rtspUrl){
videoView.setVideoURI(Uri.parse(rtspUrl));
videoView.requestFocus();
videoView.start();
}
}