- Timer-interrupt
2014年12月28日 星期日
2014年12月7日 星期日
[Raspberry-Pi] 相機模組 x Live555MediaServer
想找到可以遠端觀看Pi-Camera Live-Stream的方法,而且要有一定的即時性,只是嘗試過幾招都不是很理想:
- Motion
偵測到背景改變後才開始錄影,就監視攝影機來說是省去錄影空間的好解法,但也因此CPU運算個沒停,即時影像輸出是很不流暢的。
參考1:http://www.instructables.com/id/Raspberry-Pi-as-low-cost-HD-surveillance-camera/?ALLSTEPS
參考2:http://www.instructables.com/id/Raspberry-Pi-Completely-Wireless-IP-Camera-Solar/
- MJPG-Streamer(live streamer only)
參考1:http://blog.miguelgrinberg.com/post/stream-video-from-the-raspberry-pi-camera-to-web-browsers-even-on-ios-and-android
參考2:https://dotblogs.com.tw/bowwowxx/2015/06/08/151511
參考3:解決/dev/video0 does not support streaming i/o
參考4:照此官方步驟安裝uv4l(驅動Raspberry原廠相機至/dev/video0)
20150526備註:
消掉UVCIOC_CTRL_ADD - Error: Inappropriate ioctl for device的作法
$mjpg_streamer -i "input_uvc.so -n" -o "output_http.so -w ./www" //input_uvc.so引數加上-n
最後因緣際會瞭解了RTSP(Real Time Streaming Protocol),是種強調即時傳送串流的協定,看了維基百科的介紹,想像起來可能是偏向時間性的傳送協定,所以目標就暫時聚焦在找到實現RTSP的服務啦!
很幸運的Linux上有Live555這個開源軟體,可以讓我們架起簡單的Media Server
官方參考:Live555 Media Server
簡單作法如下:
- Step1-下載與編譯Live555(參考http://www.live555.com/liveMedia/#config-unix):
#wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz //下載Live555原始碼
#tar -zxvf live555-latest.tar.gz //解壓縮
#cd live //至live 資料夾
#./genMakefiles linux //按linux架構產生Make檔案
註1:live資料夾下有許多開頭為config.xxxx的檔案,即為對應的genMakefiles組態檔案。
註2:以"linux"架構編譯的執行檔是可以在Pi上運作的,其他架構的還沒試過。
#make //編譯Live555
#make install //佈署編譯後的Live555
註:在Pi上部屬後的Live555執行檔們會被複製到 /usr/local/bin下
- Step2-啟動Live555MediaServer
#cd /usr/local/bin // 進到Live555的佈署資料夾
#./live555MediaServer & // 啟動live555MediaServer,會秀出簡單的說明
此時live555MediaServer就被啟動了並開始連入需求的監聽,播放來源檔案路徑是相對於live5執行檔位置開始計算,也就是說,想要被播放的檔案必須與live555MediaServer執行檔放在一起,或是在其位置下的子資料夾
- Step3-啟動Pi-Camera
(在此之前要先設定好Pi-Camera唷,可以參考http://www.raspberrypi.org/learning/python-picamera-setup/)
#touch rpi.264 // 開一空檔案準備給Pi-Camera作緩衝
註:live555以副檔名辨認播放格式,此處以h264來錄影與播放
#raspivid -t 999999 -h 180 -w 270 -o rpi.264 //啟動Pi-Camara,並將串流存在rpi.264檔案裡
好的,做到這邊就完成RTSP Server側的簡單設定了,接著要到Client側開串流來看看。
- Step4-使用VLC觀看線上串流(On Windows)
在VLC下的檔案->開啟網路串流
網址輸入:
rtsp://hostname:8554/rpi.264(因為Step3的串流是輸出到與live555Server同層的檔案裡)
就可以看見流暢的影像啦!
只是…怎麼Time-shifting這麼多哩…覺得是影像在Pi上緩衝太多的關係
這點解決的話就完美了!
To Be Continued....
其他參考:
網路後端的工作筆記
大隻熊的部落格
Python-Camera // 用Python來控制嚕,進階使用
[LINUX] 快速設定網路磁碟機-SAMBA
最近猛烈的玩起了PI,有時候要從WINDOWS筆電傳檔案給PI,此時不得不倚靠SAMBA了。
這篇筆記主要參考自鳥哥(鳥哥:第十六章、檔案伺服器之二: SAMBA 伺服器)但在這裡只紀錄慣用懶人設定嚕
設定目標:分享LINUX下的帳號資料夾(home),權限管控為LINUX上的User
#apt-get install samba
#apt-get install samba-common-bin // 在Pi上,這套件是用來取testparm指令的
註解:在Raspbian上安裝後,啟動smbd會有錯誤(nmbd無法啟動,大概是被其他服務卡住),必須重開機,smbd(SAMBA服務)從此過後會於init.d自動載入
#cp /etc/samba/smb.conf /etc/samba/smb.conf.master //複製一份原始參數檔來修改
#vim /etc/init.d/samba/smb.conf .master //改在複製品上
[global]下的設定都不用改!預設的登入方式會是user(以帳號登入)
[home]下改變設定:
browseable = yes //此分享可被瀏覽
read only = no //開放家資料夾可寫入
create mask = 0775 //開放檔案讀寫權限
directory mask = 0775 //開放資料夾讀寫權限
註:當valid users = %s , 只能以\\server\username的方式掛載網路磁碟機 否則,可用\\server\home的方式 或是 \\server\labelname 的方式 掛載網路磁碟機 (標籤名等於分享名稱)
在上面的Comment欄位內,原作者建議使用testparm來管理smb.conf,會有檢查參數以及精簡設定的效果
#testparm -s smb.conf.master > smb.conf //用testparm檢查參數語法是否正確,並套用在smb.conf上
鳥哥:在 SAMBA 上面的使用者帳號,必須要是 Linux 帳號中的一個!
所以先在LINUX環境下設定要登入的SAMBA帳號密碼
#useradd username
#passwd username
接著在SAMBA帳號資料庫加入帳號
#pdbedit -a -u username // username必須要在linux帳號內存在
建立samba user , 建立時會要求輸入密碼 , 此密碼是用在WINDOWS掛載網路磁碟機用的!
註解:在遠端側瀏覽、寫入、讀取檔案,全部透過linux uid 做檔案權限控制,簡單的說,根據username在linux下的權限賦予遠端操作檔案權限
#service smbd restart
在我的電腦上右鍵->連線網路磁碟機
代號隨便填,
資料夾填\\server\username(這是因為SAMBA設定valid user = %s的關係)
帳號:剛剛加入的帳號名 username
密碼:pdbedit指令設定的密碼
備註: 在CentOS下,SAMBA服務可能會被selinux擋住,此時要去作selinux進階設定
鳥哥-SELinux 的相關議題
大功告成~
後記1:pdbedit -L -v (列出所有使用者,忘記有哪些帳號時可以回想一下)
這篇筆記主要參考自鳥哥(鳥哥:第十六章、檔案伺服器之二: SAMBA 伺服器)但在這裡只紀錄慣用懶人設定嚕
設定目標:分享LINUX下的帳號資料夾(home),權限管控為LINUX上的User
- Step1-安裝SAMBA:
#apt-get install samba
#apt-get install samba-common-bin // 在Pi上,這套件是用來取testparm指令的
註解:在Raspbian上安裝後,啟動smbd會有錯誤(nmbd無法啟動,大概是被其他服務卡住),必須重開機,smbd(SAMBA服務)從此過後會於init.d自動載入
- Step2-設定SAMBA:
#cp /etc/samba/smb.conf /etc/samba/smb.conf.master //複製一份原始參數檔來修改
#vim /etc/init.d/samba/smb.conf .master //改在複製品上
[global]下的設定都不用改!預設的登入方式會是user(以帳號登入)
[home]下改變設定:
browseable = yes //此分享可被瀏覽
read only = no //開放家資料夾可寫入
create mask = 0775 //開放檔案讀寫權限
directory mask = 0775 //開放資料夾讀寫權限
註:當valid users = %s , 只能以\\server\username的方式掛載網路磁碟機 否則,可用\\server\home的方式 或是 \\server\labelname 的方式 掛載網路磁碟機 (標籤名等於分享名稱)
在上面的Comment欄位內,原作者建議使用testparm來管理smb.conf,會有檢查參數以及精簡設定的效果
#testparm -s smb.conf.master > smb.conf //用testparm檢查參數語法是否正確,並套用在smb.conf上
- Step3-設定SAMBA帳號
鳥哥:在 SAMBA 上面的使用者帳號,必須要是 Linux 帳號中的一個!
所以先在LINUX環境下設定要登入的SAMBA帳號密碼
#useradd username
#passwd username
接著在SAMBA帳號資料庫加入帳號
#pdbedit -a -u username // username必須要在linux帳號內存在
建立samba user , 建立時會要求輸入密碼 , 此密碼是用在WINDOWS掛載網路磁碟機用的!
註解:在遠端側瀏覽、寫入、讀取檔案,全部透過linux uid 做檔案權限控制,簡單的說,根據username在linux下的權限賦予遠端操作檔案權限
- Step4-重啟smbd
#service smbd restart
- Step5-WINDOWS側設定
在我的電腦上右鍵->連線網路磁碟機
代號隨便填,
資料夾填\\server\username(這是因為SAMBA設定valid user = %s的關係)
帳號:剛剛加入的帳號名 username
密碼:pdbedit指令設定的密碼
備註: 在CentOS下,SAMBA服務可能會被selinux擋住,此時要去作selinux進階設定
鳥哥-SELinux 的相關議題
後記1:pdbedit -L -v (列出所有使用者,忘記有哪些帳號時可以回想一下)
2014年11月27日 星期四
[.NET] Lambda 中參考變數生命週期
Lambda,請念作浪打,就是希臘字母中的λ(波長) 不知道在那一代.NET體系後就出現了這個有趣的特性
簡單的說,Lambda-Expression是一種匿名函式的描述方式,我的習慣裡,通常配合Delegate一起服用(即時性的產生函式物件) 寫法長成這樣:
ByReference物件生命週期並不是離開函式Scope就消失,
而是不再有人參考到此物件時,這飄渺在記憶體太空的虛無之物才會被GC回收,
所以可能會出現,在Lambda生成時,Lambda去參考函式局部範圍下的某個Object, 即便離開生成函式,一直到Lambda執行時,
這個Object仍然被保持住,而Lambda得以順利執行。
會有種 物件小姐 從 生成他的函式酒店 被"帶出場"的感覺(威~):
答案是1、3都可(兩者效果等價),Foreach下的Reference在Iterator進到下一格時,會全部Refresh 所以各個Lambda內參考到的物件彼此是不相同的(連結到不同指標),即便程式碼中他們都是同名的變數。
相反地,選項2用的Reference在Foreach外宣告,相當於只用一個指標去連結不同的物件 但Lambda們都是以同一個指標去參考物件,所以印出來的東西都是一樣的。
簡單的說,Lambda-Expression是一種匿名函式的描述方式,我的習慣裡,通常配合Delegate一起服用(即時性的產生函式物件) 寫法長成這樣:
static Func另外一個有趣的事情是,在CLR的記憶體模型中,delegateInstance = new Func (() => { Console.WriteLine("I was prisoned in Lambda!!!"); return 0; });
ByReference物件生命週期並不是離開函式Scope就消失,
而是不再有人參考到此物件時,這飄渺在記憶體太空的虛無之物才會被GC回收,
所以可能會出現,在Lambda生成時,Lambda去參考函式局部範圍下的某個Object, 即便離開生成函式,一直到Lambda執行時,
這個Object仍然被保持住,而Lambda得以順利執行。
會有種 物件小姐 從 生成他的函式酒店 被"帶出場"的感覺(威~):
static int createLambda() { String theInstance = "I was created in createLambda()"; delegateInstance = new Func最後分享一個案例,若在Foreach中想要替陣列裡的每個物件創造對應的Lambda,在Lambda執行時,能反應陣列裡各物件的狀態(一個Lambda反應一個物件) 此時放在Lambda內的應該要用哪個具名參考?(() => { Console.WriteLine(theInstance.ToString()); return 0; }); return 0; } static int executeLambda() { delegateInstance(); return 0; } static void Main(string[] args) { createLambda(); executeLambda(); //' theInstance still kept, so that no NullReferenceException would raise }
- Iterator?
- 在Foreach外宣告一個參考?
- 在Foreach內宣告參考?
static void Main(string[] args) { ListtheList = new List (); Random rnd = new Random(); Console.WriteLine("Peek answers"); for (int i = 0; i < 10; i++) { myClass instance = new myClass(); instance.myString = rnd.Next().ToString(); theList.Add(instance); Console.WriteLine(instance.ToString()); } Console.WriteLine("Peek over"); delegateInstance = null; //myClass tempReference ; // option 2 foreach (myClass item in theList) { //myClass tempReference = item; // option 3 //tempReference = item; delegateInstance += new Func (() => { //Console.WriteLine(tempReference.ToString()); Console.WriteLine(item.ToString()); // option 1 return 0; }); } Console.WriteLine("Lambda run"); delegateInstance(); // the invocation list Console.WriteLine("Lambda finish"); }
答案是1、3都可(兩者效果等價),Foreach下的Reference在Iterator進到下一格時,會全部Refresh 所以各個Lambda內參考到的物件彼此是不相同的(連結到不同指標),即便程式碼中他們都是同名的變數。
相反地,選項2用的Reference在Foreach外宣告,相當於只用一個指標去連結不同的物件 但Lambda們都是以同一個指標去參考物件,所以印出來的東西都是一樣的。
2014年11月15日 星期六
[.NET] TCP使用筆記1--物件序列化/反序列化傳送接收
將物件序列化後傳送串流 ------> 收到串流後反序列化還原物件
其中BinaryFormatter可用在任何串流的序列化/反序列化(檔案串流、網路串流、記憶體串流…等等) ,
可延伸此法將物件資料存入/讀出磁碟,比方機台參數設定...等等,或是做大型物件的記憶體內複製(應用記憶體串流)。
Import System.Runtime.Serialization.Formatters.Binary <Serializable()> Public Class MySerializableClass ' Define a Class which is able to be serialized ' Property s As String = "abcdedfg" Property i As Integer = 50 Property f As Double = 3.14159256 End Class Dim clientSend As TcpClient = New TcpClient() 'used to send stream' Dim clientReceive As TcpClient = new TcpClient() 'used to receive stream' Sub serializeAndSend() Dim bf As BinaryFormatter = New BinaryFormatter() bf.Serialize(clientSend.GetStream(), New MySerializableClass()) ' Serialize object and write into net-stream ' End Sub Function receiveAndDeserialize() As Object Dim bf As BinaryFormatter = New BinaryFormatter() return bf.Deserialize(clientReceived.GetStream()) ' stream received and deserialize to object' End Function
其中BinaryFormatter可用在任何串流的序列化/反序列化(檔案串流、網路串流、記憶體串流…等等) ,
可延伸此法將物件資料存入/讀出磁碟,比方機台參數設定...等等,或是做大型物件的記憶體內複製(應用記憶體串流)。
2014年11月8日 星期六
Windows網路橋接器 + Raspberri PI
筆記一下消耗我兩晚青春的Windows網路橋接器…
這次要搞定的拓樸結構長這樣:
目標是讓Raspberry PI 還有 筆電 都可以透過Wifi Router上網
首先先建立Windows網路橋接器,將筆電的Wifi介面與Ethernet介面橋接起來:
橋接後照著原先的習慣,讓筆電連接Wifi,
並設定"自動取得IP",讓網路橋接器以DHCP協定向Router要到IP:
Rasperry PI 這邊就要特別注意了,
必須手動設定 靜態IP、子網路遮罩、Gateway,
若以dhclient是要不到DHCPPACK的,因為透過網路橋接器發出的DHCPDISCOVER是以網路橋接器MAC為訊框,導致Router也一直將封包回錯對象,以至於Raspberry PI無法取得動態IP。
(檢查方法:查Router的 /var/log/syslog , 裡面的DHCP相關Log可以發現這個線索)
手動設定的方法如下:
#sudo vi /etc/network/interfaces //編輯網路設定檔案
加入此行:
gateway 192.168.0.1 #可照著上圖的IPv4預設閘道設定
如此一來就沒問題了
這次要搞定的拓樸結構長這樣:
目標是讓Raspberry PI 還有 筆電 都可以透過Wifi Router上網
首先先建立Windows網路橋接器,將筆電的Wifi介面與Ethernet介面橋接起來:
橋接後照著原先的習慣,讓筆電連接Wifi,
並設定"自動取得IP",讓網路橋接器以DHCP協定向Router要到IP:
Rasperry PI 這邊就要特別注意了,
必須手動設定 靜態IP、子網路遮罩、Gateway,
若以dhclient是要不到DHCPPACK的,因為透過網路橋接器發出的DHCPDISCOVER是以網路橋接器MAC為訊框,導致Router也一直將封包回錯對象,以至於Raspberry PI無法取得動態IP。
(檢查方法:查Router的 /var/log/syslog , 裡面的DHCP相關Log可以發現這個線索)
手動設定的方法如下:
#sudo vi /etc/network/interfaces //編輯網路設定檔案
加入此行:
auto eth0
iface eth0 inet static
address 192.168.0.51 #注意要跟Router同網域,而且此IP未被其它人佔用
netmask 255.255.255.0
network 192.168.0.254 #注意要跟Router同網域
broadcast 192.168.0.255
#注意要跟Router同網域gateway 192.168.0.1 #可照著上圖的IPv4預設閘道設定
如此一來就沒問題了
訂閱:
文章 (Atom)