vlcandroid開發
Ⅰ 如何用 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 菜單。
可以在有來電時自動暫停媒體播放。
Ⅱ vlc for android怎麼播放spydroid
最近在做android視頻點對點的聊天項目。
自己在網上找到了spydroid開源項目,可以發送rtsp流。
然後我用vlc for android來播放,在android手機上單獨是可以實時播放的。
然後我對vlc項目代碼整合到spydroid項目中,可以跑起來,點擊播放也可以連接上spydroid,spydroid也有相應,
但是整合後播放顯示不了rtsp流,求高手分析分析,謝謝。
log如下:
04-09 11:09:49.998: V/VLC/AudioService(2184): Loading position 0 in [rtsp://192.168.1.238:8086]
04-09 11:09:50.008: V/VLC/AudioService(2184): Creating on-the-fly Media object for rtsp://192.168.1.238:8086
04-09 11:09:50.008: D/VLC(2184): main playlist: no fetch required for (null) (art currently (null))
04-09 11:09:50.008: D/VLC/MediaItem(2184): Title rtsp://192.168.1.238:8086
04-09 11:09:50.018: D/VLC/MediaItem(2184): Artist Unknown Artist
04-09 11:09:50.018: D/VLC(2184): main demux meta: looking for meta fetcher
Ⅲ androidvlc集成以及了解vlc架構有哪些
VLC是一個功能強大的開源媒體播放器,其架構和流程設計使得其具備高度的可擴展性和靈活性。本文將從整體架構、重要概念、模塊管理和流程分析幾個方面,概述VLC的集成和架構。
VLC的架構設計主要圍繞一系列模塊,這些模塊封裝了不同的功能,如訪問、解碼等。整體框架由VLC主模塊、核心模塊、模塊和外部庫組成。VLC主模塊負責初始化和載入用戶界面,核心模塊提供libvlc_instance_t對象,管理模塊的裝載和卸載,而模塊則提供具體功能。
VLC的模塊載入方式涉及注冊和回調機制,允許開發者實現自定義模塊。模塊的載入流程通常涉及模塊自身注冊到VLC中,之後在需要時調用特定介面來尋找並執行注冊時設定的回調方法。VLC中的許多模塊實際上是由外部開源庫實現的。
VLC的模塊大致分為音視頻處理模塊、編碼器模塊、解碼器模塊等,涵蓋了媒體播放流程的關鍵環節。
流程分析方面,VLC的執行流程可以從啟動、初始化輸入、播放輸入等階段進行梳理。啟動時,主函數執行初始化操作,接著創建輸入源並開始初始化,最後進入播放階段,包括調用MainLoop循環執行播放流程。
總體而言,VLC以其模塊化設計和豐富的功能支持,為用戶提供了一個高度可定製和靈活的媒體播放解決方案。通過深入理解其架構和流程,開發者可以更有效地集成VLC到自己的應用中,實現復雜媒體處理任務。
Ⅳ 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();
}
}
Ⅳ 有沒有vlc對應的android 版本
Android版VLC應用正式升級至1.0.0版本;
新版修復了ARMv8處理器,Android 5.0上的崩潰問題並在細節處進行了調整;
新版全新的界面已經在黑色和白色主題中使用;
Ⅵ vlc for android 支持swf 嗎
經測試vlc無法播放swf文件,為了彌補這已缺陷,需要添加swfdec到android平台以支持swf文件。
Ⅶ 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中。