android開發vlc
1. 編譯android-vlc支持rtsp,是不是需要添加live555誰有詳細的步驟呢給說下,最好有編譯好的源碼
vlc-android是直接支持rtsp的,可以播放rtsp。http,mms網路流 我編譯好了一份源代碼,你可以下載看看 http://download.csdn.net/detail/wng2010/4971056
2. android vlc怎麼硬解碼
前幾天用PC平台上的VLC播放RTSP流媒體時延遲時間較長,存在1s左右的延遲,效果不是很好,後來查了資料,發現這個延遲時間是可以修改的。 找到工具->首選項,然後參數設置左下角選擇「全部」,左邊選擇 「輸入編解碼」->「網路緩存」選項,可以根據具體需要加以修改,具體見下圖不過這個值不要太小,否則緩存太小,播放視頻的過程中會很卡
3. 有沒有vlc對應的android 版本
Android版VLC應用正式升級至1.0.0版本;
新版修復了ARMv8處理器,Android 5.0上的崩潰問題並在細節處進行了調整;
新版全新的界面已經在黑色和白色主題中使用;
4. vlc-android要怎麼用
一.認識android的架構
Android其本質就是在標準的linux系統上增加了java虛擬機Dalvik,並在Dalvik虛擬機上搭建了一個JAVA的application framework,所有的應用程序都是基於JAVA的application framework之上。
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
二.搭建環境
搭建開發環境
對國內的開發者來說最痛苦的是無法去訪問android開發網站。為了更好的認識世界,對程序員來說,會翻牆也是的一門技術,帶你去領略牆外的世界,好了,不廢話了, 國內開發者訪問(androiddevtools) 上面已經有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進一步去實現自己的rom,我們看到錘子的系統在早期的開放rom是自己從新實現了framework的代碼,現在看起來他成功了,所以我們還要去搭建android系統的源碼編譯環境。
搭建源碼編譯環境
http://www.cnblogs.com/bluestorm/p/4419135.html
https://source.android.com/source/downloading.html(這里詳細的介紹了如何下載編譯)
三.開始主題
在一開始寫c程序的時候都有一個運行的入口,比如
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//這里的main就是應用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計算機網路原理中我們用socket實現一個伺服器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實現的:
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#include <stdio.h>
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//載入套接字型檔,如果失敗返回
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return;
}
//判斷高低位元組是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創建流式套接字,基於TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結構體的創建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉換Unsigned long型為網路位元組序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定埠號,除sin_family參數外,其它參數都是網路位元組序,因此需要轉換
//將套接字綁定到一個埠號和本地地址上
bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結構體
int len = sizeof(SOCKADDR);//初始化參數,這個參數必須進行初始化,sizeof
//循環等待接受客戶端發送請求
while (1)
{
//等待客戶請求到來;當請求到來後,接受連接請求,
//返回一個新的對應於此次連接的套接字(accept)。
//此時程序在此發生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發送一個位元組
//接收數據
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他採用了一個while死循環去監聽客戶端的請求。
在一遍啰嗦之後,主角終於閃亮的登場了。
先上源代碼
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
//從中可以看到為app開辟了一個線程進入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源碼失望了,沒有一個while循環啊,其實用了他方法實現
//用一個looper的機制循環監聽響應
Looper.prepareMainLooper();
Looper.loop();
進一步深入代碼
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在這里看到了一個循環監聽消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that ring the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
5. android 如何使用vlc進行二次開發
到vlc官網下載vlc
for
android工程,就可以進行二次開發。看你需要什麼內容,我這邊也有一個調試好的工程,需要就加我QQ463855700
6. 做android視頻播放器用vlc和達爾文故武器搭配使用有問題嗎
1、不能播放
現象:播放器打開後,緩沖一段時間,彈出播放失敗
范圍:所有Android設備,但是vlc player可以播放
原因:H.264視頻的SPS、PPS沒有發送。雖然在DESCRIBE的sdp應答裡面已經通過config欄位返回了SPS、PPS,但是Android上的播放器忽略了這個,還是需要在RTP流中增加冗餘數據。
方案:RTP流中增加冗餘的SPS、PPS數據
備註:實現完RTSP服務端後,在VLC上測試可以播放,但是在所有Android設備都不能播,尋找各種原因都沒有結果,一度都覺得乾脆放棄算了。這件事告訴了我們:永不放棄,在一次次失敗後,你離成功就只有一步了。
2、無圖像
現象:播放器打開後,有聲音無圖像
范圍:部分影片,部分設備
原因:通過分析影片,發現不能播放的都是H.264 High Profile,設備硬體不支持。
方案:改成H.264 Baseline壓縮
7. 如何將vlc嵌入到android中
做vlc-android移植的道友都應該知道,當編譯完vlc-android 源碼後EventManager.java
類中定義了許多事件,下面是源碼一部分:
public class EventManager {/*
* Be sure to subscribe to events you need in the JNI too.
*///public static final int MediaMetaChanged = 0;
//public static final int MediaSubItemAdded = 1;
//public static final int MediaDurationChanged = 2;
//public static final int MediaParsedChanged = 3;
//public static final int MediaFreed = 4;
//public static final int MediaStateChanged = 5;//public static final int MediaPlayerMediaChanged = 0x100;
//public static final int MediaPlayerNothingSpecial = 0x101;
//public static final int MediaPlayerOpening = 0x102;
//public static final int MediaPlayerBuffering = 0x103;
public static final int MediaPlayerPlaying = 0x104;
public static final int MediaPlayerPaused = 0x105;
public static final int MediaPlayerStopped = 0x106;......
}
可是對於這些事件有很多都被注釋掉了,當我們需要被注釋掉的事件時,就算把注釋拿掉,再調用mEventManager.addHandler(EventManager.getInstance())添加事件之後,也不會在定義的mEventHandler
的handleMessage()中監聽到,下面為一個mEventHandler定義的demo:
[java] view plain
private final VideoEventHandler mEventHandler = new VideoEventHandler(this);
private class VideoEventHandler extends WeakHandler<DtvPlayer>{
public VideoEventHandler(DtvPlayer owner) {
super(owner);
}
@Override
public void handleMessage(Message msg) {
DtvPlayer activity = getOwner();
if(activity == null) return;
switch (msg.getData().getInt("event")) {
case EventManager.MediaPlayerBuffering:
Log.d(TAG, "MediaPlayerBuffering");
break;
case EventManager.MediaPlayerEncounteredError:
Log.d(TAG, "MediaPlayerEncounteredError");
break;
......
default:
Log.e(TAG, String.format("Event not handled (0x%x)", msg.getData().getInt("event")));
break;
}
super.handleMessage(msg);
}
}
那麼如何才能夠在mEventHandler中監聽到我們需要的事件呢,下面將進入主題。
在libvlcjni.c中有一個靜態常量,其中指定了我們目前需要獲取哪些事件:
[html] view plain
static const libvlc_event_type_t mp_events[] = {
libvlc_MediaPlayerPlaying,
libvlc_MediaPlayerPaused,
libvlc_MediaPlayerEndReached,
libvlc_MediaPlayerStopped,
libvlc_MediaPlayerVout,
libvlc_MediaPlayerPositionChanged
};
你可以將自己需要的事件添加在裡面,然後將EventManager中響應的事件注釋拿掉,之後重新編譯源碼就可以再mEventHandler中獲取你剛添加的事件了。
(例如:你要想獲取MediaPlayerEncounteredError事件,先將libvlc_MediaPlayerEncounteredError添加在mp_events[]靜態常量中(注意,這里前面多了libvlc_),然後把EventManager中的public
static final int MediaPlayerEncounteredError =
0x10a;注釋拿掉,重新編譯源碼之後就可以在你得mEventHandler
的handleMessage()中獲取到EventManger.MediaPlayerEncounteredError事件)。
在vlc-android/vlc/lib/event.c中定義了所有事件:
[cpp] view plain
#define DEF( a ) { libvlc_##a, #a, },typedef struct
{
int type;
const char name[40];
} event_name_t;static const event_name_t event_list[] = {
DEF(MediaMetaChanged)
DEF(MediaSubItemAdded)
DEF(MediaDurationChanged)
DEF(MediaParsedChanged)
DEF(MediaFreed)
DEF(MediaStateChanged)DEF(MediaPlayerMediaChanged)
DEF(MediaPlayerNothingSpecial)
DEF(MediaPlayerOpening)
DEF(MediaPlayerBuffering)
DEF(MediaPlayerPlaying)
DEF(MediaPlayerPaused)
DEF(MediaPlayerStopped)
DEF(MediaPlayerForward)
DEF(MediaPlayerBackward)
DEF(MediaPlayerEndReached)
DEF(MediaPlayerEncounteredError)
DEF(MediaPlayerTimeChanged)
DEF(MediaPlayerPositionChanged)
DEF(MediaPlayerSeekableChanged)
DEF(MediaPlayerPausableChanged)
DEF(MediaPlayerTitleChanged)
DEF(MediaPlayerSnapshotTaken)
DEF(MediaPlayerLengthChanged)
DEF(MediaPlayerVout)DEF(MediaListItemAdded)
DEF(MediaListWillAddItem)
DEF(MediaListItemDeleted)
DEF(MediaListWillDeleteItem)DEF(MediaListViewItemAdded)
DEF(MediaListViewWillAddItem)
DEF(MediaListViewItemDeleted)
DEF(MediaListViewWillDeleteItem)DEF(MediaListPlayerPlayed)
DEF(MediaListPlayerNextItemSet)
DEF(MediaListPlayerStopped)DEF(MediaDiscovererStarted)
DEF(MediaDiscovererEnded)DEF(VlmMediaAdded)
DEF(VlmMediaRemoved)
DEF(VlmMediaChanged)
DEF(VlmMediaInstanceStarted)
DEF(VlmMediaInstanceStopped)
DEF(VlmMediaInstanceStatusInit)
DEF(VlmMediaInstanceStatusOpening)
DEF(VlmMediaInstanceStatusPlaying)
DEF(VlmMediaInstanceStatusPause)
DEF(VlmMediaInstanceStatusEnd)
DEF(VlmMediaInstanceStatusError)
};
#undef DEF
其中DEF()將MediaPlayerEncounteredError定義為libvlc_MediaPlayerEncounteredError,當本地代碼產生MediaPlayerEncounteredError事件時會將libvlc_MediaPlayerEncounteredError傳遞給jni,與此同時jni又會傳遞給java層。不管是本地libvlc_MediaPlayerEncounteredError還是java層MediaPlayerEncounteredError,對於同一個事件被定義的值都是相同的,傳輸的是同一個消息值。本地代碼定義在vlc-android/vlc/include/libvlc_events.h,
java代碼定義在EventManager.java中。
轉載
8. 如何使用vlc開發一個新的安卓播放器
安卓這邊有哪些不錯的播放器呢 最近我也在找 主要是要能播rtmp的開源的有vlc,ijkpler(這個是B站做的),還有vitamio,vitamio是個人開發者免費使用,公司使用要收費。接觸android視頻播放這一塊之後我才知道有多蛋疼。我上面給的那個github的項目可以直接用了,是基於VLC的,不過只支持arm的cpu,,而且版本比較老
9. vlc android要怎麼調用
做vlc-android移植的道友都應該知道,當編譯完vlc-android 源碼後EventManager.java
類中定義了許多事件,下面是源碼一部分:
public class EventManager {/*
* Be sure to subscribe to events you need in the JNI too.
*///public static final int MediaMetaChanged = 0;
//public static final int MediaSubItemAdded = 1;
//public static final int MediaDurationChanged = 2;
//public static final int MediaParsedChanged = 3;
//public static final int MediaFreed = 4;
//public static final int MediaStateChanged = 5;//public static final int MediaPlayerMediaChanged = 0x100;
//public static final int MediaPlayerNothingSpecial = 0x101;
//public static final int MediaPlayerOpening = 0x102;
//public static final int MediaPlayerBuffering = 0x103;
public static final int MediaPlayerPlaying = 0x104;
10. 如何用 Android 手機遠程式控制制 Linux 桌面 VLC 播放器
准備條件
Android 手機和桌面 Linux 位於同一無線網路,是否可以訪問互聯網不重要。
Android 手機上安裝免費開源的 Remote for VLC(Code 首頁)
已經在 Linux 桌面環境下安裝好 VLC 2.0 播放器。
下文將以 Fedora 17 為例介紹這一過程。
啟用 VLC http 遠程式控制制支持
啟動 VLC,在主界面上依次點擊「工具」-「首選項」-左下角選擇「全部」-左側列表中選擇「主界面」-在右側勾選「Web」。如下圖所示:
保存並關閉 VLC。
之後需要編輯 VLC 的 Lua 主機配置文件,允許可以訪問的網路段。比如可以用以下命令以 root 用戶身份打開配置文件:
su -c 'vim /usr/share/vlc/lua/http/.hosts'
一般正常的人會僅希望區域網內的 Android 手機可以訪問並控制桌面上的 VLC,於是取消 # private addresses下面幾行開頭的注釋即可。
保存更改並退出編輯器。
設置防火牆策略
找到系統設置中的防火牆,或者通過在終端輸入 system-config-firewall 的方式啟動。
VLC 的遠程式控制制默認通過 8080 埠實現,所以在左側選擇「其他埠」,然後通過右側依次添加 TCP/UDP 8080 埠。
(可選)Android 手機支持通過 Avahi 的方式自動尋找查找網路中的可用主機,如果需要這個功能的話在左側選擇「可信的服務」,然後在右側勾選「多點廣播 DNS (mDNS)」。如果不用啟用該項的話就需要在 Remote for VLC 手動輸入 IP 地址和埠。
完成之後點擊工具欄上的「應用」保存防火牆配置。
開始使用
再次啟動 VLC 播放器,在主界面上選擇「視圖」-「添加界面」-選擇「Web」。
在 Android 手機上啟動 Remote for VLC,稍等一下應該就會顯示在網路中找到的所有 VLC 實例,輕觸即可鏈接。
此時你就可以遠離鍵盤和滑鼠,坐在沙發上享受 VLC 帶來的影音體驗了:
支持音量、音軌、字幕軌、全屏模式的調整,顯示媒體信息。
支持創建播放列表。
支持瀏覽桌面 Linux 上的文件系統(知道為何不建議通過互聯網訪問了吧……)
試驗性的支持 DVD 菜單。
可以在有來電時自動暫停媒體播放。