顯示具有 Remote Control 標籤的文章。 顯示所有文章
顯示具有 Remote Control 標籤的文章。 顯示所有文章

2024-06-26

用mpv做簡報

 前面提到用mpv可以看youtube並且載入不同語文的字幕,後來想到是不是可以利用自製的vtt格式字幕來搭配mpv播放影片做簡報?

 一樣是影音播放軟體,VLC可能比mpv更出名,但我認為mpv比VLC好用,因為mpv可以在command line加上各種參數或由script來執行,達到把各種組合自動化的結果。

 這個試作是以最基本的簡報為目標,只用「圖片+文字」來構成,對於不想使用現成簡報軟體的時候,mpv是個不錯的選項,可以透過python或bash script呼叫ffmpeg,把「圖片、文字」組合成影片,再交給mpv播放,就達到基本簡報的目的了。

 關於影片製作以及字幕時序,是以每一秒換一張圖、一次字幕來算,或許會懷疑一秒不是太快了?不會!因為可以控制mpv的播放速度,如果設為0.1倍,原本的速度就變成10秒換一張圖、一次字幕的簡報速度。如果10秒不夠,那就按下暫停在某一張圖,便有充裕的時間進行講解,然後前進到下一個畫面,直到結束。

 vtt字幕的格式,以"WEBVTT"為第一行。
-----------
WEBVTT

1
00:00:00.000 --> 00:00:00.900
簡報文字第一行
簡報文字第二行

2
00:00:01.000 --> 00:00:01.900
簡報文字第三行
簡報文字第四行

3
00:00:02.000 --> 00:00:02.900
簡報文字第五行
簡報文字第六行

-----------
將文字檔存成例如 present.vtt 的檔名。1是搭配第一張圖的文字,2就是搭配第二張圖的文字,以此類推,可以只用一行,或很多行也可以,字很多的話,再把字體調小一些。

假設有十張圖要做簡報,我們用ffmpeg來組合圖片變成影片:
ffmpeg -framerate 1 -pattern_type glob -i 'present*.jpg' -c:a copy -c:v libx264 -r 1 present.mp4
"-framerate 1" 是一秒一張圖的意思(一般影片是30fps,一秒播30張圖),之後用mpv來播放時再把速度放慢到 "--speed=0.1" 就是一秒的十分之一,變成一張圖停留10秒(最慢可以設成 0.01秒,就是一張圖會停留100秒)。

然後在播放影片時,帶上自己做的字幕,播放時用的最基本參數是:
mpv --speed=0.1 present.mp4 --sub-file=present.vtt

mpv帶字幕時還有很多參數可用像是:
 --sub-border-color=\#000000\
 --sub-border-size=3\
 --sub-color=\#d0d0a0\
 --sub-shadow-color=\#2020d0\
 --sub-shadow-offset=15\
 --sub-back-color=\#3506080a\
 --sub-visibility=yes \
 --sub-align-x=left \
 --sub-align-y=top \
 --sub-pos=95\
 --speed=0.1\
(詳細說明請參考man mpv)

這樣製作出來的簡報mp4影片及自製字幕vtt加起來體積很小,很方便攜帶或傳送。

如果有RP2040微控器,也就是Pi Pico或Waveshare Zero之類的,焊上一個紅外線接收器,可以搭配circuitpython加上irremote(紅外線遙控)以及 adafruit-hid 來模擬鍵盤。
circuitpython的code.py可以加上以下模擬鍵盤的控制

kbd.send(Keycode.SPACE) #mpv 暫停/播放
kbd.send(Keycode.V) #mpv 字幕 顯示/隱藏
kbd.send(Keycode.LEFT_ARROW) #mpv 倒退10秒
kbd.send(Keycode.RIGHT_ARROW) #mpv 前進10秒
kbd.send(Keycode.SHIFT, Keycode.LEFT_ARROW) #mpv 倒退1秒
kbd.send(Keycode.SHIFT, Keycode.RIGHT_ARROW) #mpv 前進1秒
kbd.send(Keycode.R) #mpv 字幕上升
kbd.send(Keycode.SHIFT, Keycode.R) #mpv 字幕下降
kbd.send(Keycode.SHIFT, Keycode.G) #mpv 字體變大
kbd.send(Keycode.SHIFT, Keycode.F) #mpv 字體變小
(這些都是mpv內建控制播放用的按鍵。)

2024-03-16

隨手關歪壞(Wifi)

日常生活中大家常說「要隨手關燈、要隨手關水龍頭」,但是沒有人說「要隨手關歪壞」?一來是人們使用歪壞也沒幾年,對歪壞認識不多,反正種花電信來安裝,可以用就好了,沒想過要關掉。二是歪壞設備大部份是沒有像電燈的開關,沒辦法讓人按一下就關、就開。

大部份歪壞設備要透過網路從瀏覽器畫面登入,再慢慢翻頁到可以關或開的選項,然後進行設定,而且幾乎只有透過時程控管開或關,沒有按一下就開或關的,而且按一下設定之後,還要等一段時間讓歪壞重新啟動才能生效。

現在市售歪壞設備更是標榜「穿牆」,功率越強越好,賣方跟買方都有這樣訴求。所以我們打開歪壞一掃,左右鄰居的AP名字都會出現,有的甚至比你家裡的更強!

嚴格一點來看,歪壞訊號到處射,也會有安全上的隱憂吧?如果能「隨手關歪壞」應該會比較安全,也比較環保。

要能夠隨手關歪壞,大概只有自己DIY一途,DIY需要哪些東西?(可能需要一點電子焊接工作) 

1.一組SBC ARM電腦,例如各種Pi,Banana pi Zero, NanoPi Neo, RPi zero……,不需要高規格硬體。
2.作業系統使用Linux,所以需要一些基本的使用經驗。
3.Wifi硬體,SBC板上內建的,或PCIe/MiniPCIe介面的,或USB介面的,最好有外接天線。(可能會遇到某些硬體沒有支援AP mode,或需要自行compile driver,要實際試才知道)
4.紅外線接收頭(有些SBC會內建),網路買一個5元以內(搜尋1838B這一款),紅外線發射器(家裡不用的紅外線遙控器,或壞掉只剩一個按鍵正常的遙控器,因為我們只要用一個鍵就夠了)
5.一個LED(可以是onboard的或接在GPIO腳上)來顯示歪壞On/Off,或是接一個WS2812(NeoPixel)多彩LED,這個好用,只要三支GPIO就能控制幾十個RGB LED。
6.板上內建的MCU或外接的MCU(例如RPi pico 或 RP2040-zero),用來解讀紅外線訊號,下指令控制歪壞的開、關。
7.用某種語言來寫控制介面,例如常見的python,以及MCU上面的程式(例如circuitpython)。
8.底層控制程式,一為控制AP的hostapd,另一為dhcpd(可以用dnsmasq或是更簡便的busybox udhcpd)分配IP,以及routing, iptables NAT給client端。

SBC上面內建紅外線接收頭是最方便的,如果沒有,就要在GPIO上面插紅外線接收頭,如果從GPIO插有問題,那就把紅外線接收頭插在USB外接式MCU(RPi pico 或RP2040-zero)上面也可以。

解碼紅外線發射器的某個按鍵所發出來訊號的值,如果是內建MCU,可以在SBC上面執行例如"sudo ir-keytable -c -t"來讀取按鍵值,以便寫入介面程式。如果用RPi pico或RP2040-zero這種外接MCU,可以用"adafruit_irremote"這個circuitpython用的library來讀取按鍵值。

用bash寫一個同時啟動dhcpd以及hostapd的介面程式。

最後寫一個銜接MCU到OS的介面程式,來「開」「關」歪壞AP。
1.紅外線『發射器』送出訊號
2.紅外線『接收頭』收到訊號
3.MCU確認這個訊號是要控制歪壞AP,而非其他按鍵
4.MCU向介面程式傳達『收到了』
5.介面程式檢查hostapd,若是未執行,就執行bash介面,啟動hostapd及dhcpd
6.介面程式檢查hostapd,若是執行中,就執行bash介面,中斷hostapd及dhcpd

完成之後,按下遙控器上某一個鍵,歪壞就開啟,LED就亮,再按一下同一鍵,歪壞就關閉,LED就滅,這樣就能「隨手關歪壞」了。

2023-03-31

pico解譯各種紅外線訊號

利用Raspberry Pi Pico + Adafruit 的 IR remote library 來做個泛用型紅外線接收器,插到電腦的USB就可以用來遙控任何電腦。

https://github.com/adafruit/Adafruit_CircuitPython_IRRemote

只需要 copy adafruit_irremote.py 放到 pico 的lib/ 目錄下面即可

這裡所謂泛用是說,因為同樣是按數字「2」,但不同遙控器發射出來的訊號卻不一樣。任何市面上有的紅外線遙控器,像是控制電視、播放機、機上盒、DVD機、選台器,甚至市售萬用型紅外線遙控器也是,都可以拿來做為遙控pico用。

IR receiver 有三支腳,接到pico的GPIO腳,一支接3V3 一支接GND 一支接任何GPIO, 然後把GPIO腳的GPXX 代入 pulsein 裡,這裡以GP18為例。

import board, pulseio, adafruit_irremote
pulsein = pulseio.PulseIn(board.GP18, maxlen=128, idle_state=True)

def draw():
  decoder = adafruit_irremote.GenericDecode()
  while True:
    try:
      pulses = decoder.read_pulses(pulsein)
      code = decoder.decode_bits(pulses)
      pulses.clear()
      print(code)
    except Exception as ex:
      print(str(ex))

然後從電腦用 pyserial-miniterm /dev/ttyACM0 115200 --raw 指令就可以連上pico, 來看你用的紅外線遙控器發射什麼訊號碼?

大部份解出來的都有四組數字,以我手上的幾支發射器,解出來像是
(255, 0, 183, 72)
(255, 0, 191, 64)
(255, 0, 199, 56)
或是
(49, 107, 69, 186)
(49, 107, 203, 52)
(49, 107, 163, 92)
或是
(158, 41, 15, 240)
(158, 41, 159, 96)
(158, 41, 191, 64)
或是
(191, 191, 167, 88)
(191, 191, 143, 112)
(191, 191, 39, 216)
但也有只發射兩組數字的,像是
(29, 191)
(29, 79)
(29, 207)
(這種是市售的一種包含USB接收器的遙控組,一組一百多台幣)
以四組碼的來說,前兩碼是固定,可以用第三碼來辨識發射的是哪個鍵
而兩組訊號碼的,第一碼是固定,可以用第二碼來辨識發射的是哪個鍵

知道這些訊號碼之後,就可以搭配像是Adafruit HID linbrary 來模擬鍵盤或老鼠來控制電腦,或單純從serial port送按鍵碼給電腦來做操控。

https://github.com/adafruit/Adafruit_CircuitPython_HID

較早的版本有分給circuitpython 7 或 8 版用,現在都用 8 所以只有一個目錄
adafruit_hid
把整個目錄copy到pico lib/ 下面即可使用。
例如:

elif code[2] == 63:
    kbd.send(Keycode.CONTROL, Keycode.W)
    如果第三碼是 63 就按下 Ctrl 跟 w 關閉分頁
 

elif code[2] == 123:
    kbd.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.EQUALS)
    如果第三碼是123就按下Ctrl 跟 + 放大(zoom in)

2021-11-28

crontab定時播放音樂

最近做了一個Internet Radio, 收集了一百多個有興趣的網路電台,然後想用定時
機制來播放,當然"sleep"是一個立即可用的工具,但是要去算「睡幾分鐘」就不方便
,這時想到Linux環境下的crontab是個好用的工具,可以自由設定月、日、星期、日
、分來做一些原本要手工啟動的工作。

它的基本語法就是「分 時 日 月 星 程式(參數)」

但是遇到的問題是,設定好「程式+參數」之後,時間到了確實有進行動作,但是我要的
是播放音樂叫我起床卻沒有聲音!

為了證實程式有做動作,設了一個參考檔,只有程式有動起來,就會產生參考檔。

然而在時間到的時候,參考檔有產出,喇叭卻沒發出聲音!?
一開始以為是tty的問題,試來試去也是沒聲音,最後終於找到原因,就是環境參數
XDG_RUNTIME_DIR的問題。

這個參數雖然以 X開頭,但實際上跟Xorg無關,在純console mode也需要設定它。

因此把執行程式改成獨立的script,然後在script裡面設定環境參數,如下:

export XDG_RUNTIME_DIR="/run/user/NNNN"
/PATH/music_player URL
這裡的 /run/user/NNNN 要看你電腦裡的實際字串,它可能是1000或999
這樣就能借由crontab來定時播放音樂了。

2021-02-28

在Linux環境用真實遙控器來飛虛擬飛機

 在Linux環境的crrcsim是一個能夠連接真實遙器來練習操作的軟體,就是
把真正控制飛機的遙控器透過實體線路接到serial port或USB port就可以
操作crrcsim裡的各種飛機。

多年前一台亞拓(ALIGN)的飛機摔壞之後就沒再使用那台5 channel遙控器,
最近在Linux裡裝了crrcsim,透過serial port接到電腦之後試了一下,
可以操控crrcsim裡的飛機。

我這台電腦有內建serial port,連接與設定如下:
Options --> Control --> Input Method
選擇FMSPIC /dev/ttyS0 9600
Configure --> Custom
Aileron --> 3 Inv
Elevator --> 1
Rudder --> 0
Throttle --> 2
再進入Options --> Controls
Configure --> Calibrate
把搖桿推到最大值,校正各個操作channel
Next --> Finish --> OK
Simulation --> Restart 就可以飛了

有個問題:
日本手左邊是Elevator + Aileron 或是 Elevator + Rudder ?

2020-10-30

單層布飛行傘Single Skin Paraglider 以及OpenSource遙控器

最近看到遙控飛行傘的影片,發現跟之前的式樣不太一樣,以前認知的飛行傘是有
進氣口,但是這次看到的飛行傘是沒有進氣口,所以懷疑是因為遙控玩具,廠商為
了降低成本做成那樣。

之後繼續查google跟youtube, 發現真的有這種沒有進氣口的飛行傘,它只有
上層布,沒有下層布用來構成中間的氣室。這種叫做 single skin paraglider,
最早是2014年在遙控界開使有廠商生產,到了2019年不是遙控玩具的真正戴人的
飛行傘被廠商生產出來上市。

據youtube上面看到的計價是它甚至比傳統雙層布的飛行傘更加穩定,成本也減少,
重量減輕,收納空間也減小,有殊多好處。

在遙控器方面,不少品牌是採用OpenTX firmware, 可以考慮購買這些品牌
遙控器:
http://www.open-tx.org/radios.html

2017-12-02

telegram-cli觀察記

已經觀察了六天,發現telegram-cli拉高CPU loading的時間不一定,有時連續
一整天每個小時都出現很多(幾十次)衝到50%以上的情形,有時卻好幾個小時都
不曾出現10%以上的loading,但可以確定的是「不是OS造成程式loading high的
問題」,懷疑是網路通訊連接到telegram server有阻礙,因此一直retry導致
loading high。這六天的紀錄也沒有出現70%以上的(使用A10 single core)。

"-P XXXX"好用的地方在於telegram-cli仍可以續繼操作,又可以接受外部程式
送來的payload,並將它送出。

2017-11-26

telegram-cli 使用後記

telegram-cli使用兩年多好像沒什麼不良,但最近卻發現主機常常system reboot,
查來查去,推測是telegram-cli把CPU loading拉很高,最後引發system reboot.

好吧,那來加個監測CPU loading並且把情況回報給自己的帳號,這樣就可以找到
最後的黑盒子內容。
telegram-cli 加上 -P 2323 的參數,開一個小門來讓外部程式送訊

監視CPU的程式可以用
pn = popen('pidof telegram-cli').readline().strip()
P='top -bn1 -p %s|tail -n1|awk \'{print $9}\''%pn
while True:
   L = popen(P).readline().strip()
   如果 L 大於 10 就送個簡訊
   system('echo "msg XXX_YY %s %s"|nc localhost 2323 -q1'%(L,strftime('%T')))
   如果 L 大於 90 就把它殺了
   system('sudo pkill telegram-cli')

2017-03-31

DietPi 網路收音機

前陣子Asus低調的出了一款Tinker board, 可以說是仿Raspberry Pi, 因為
整個尺寸跟layout可以說完全跟Raspberry Pi一樣, 大概就是RAM比較大,有2G,
在台灣的售價不高於2200元.(RPi 3 大約1350元)

http://dietpi.com 是個比較特別的Raspberry Pi Linux版本, 除了是源自
Raspbian, 可以用在Raspberry Pi 之外, 還有提供給各種不同ARM SoC的版本.

它不預裝一堆你可能用不到的東西,所以整個系統可以dd到1GB的MicroSD
卡上面使用.

當然by default也就沒有Xwindow, 但因為它仍是Raspbian base, 所以可以使用
Raspbian/Debian的repository來安裝自己想要的軟體.

它有幾個特別之處,就是把常有r/w的目錄, 改成tmpfs來使用,除了可以提高
r/w速度也能延長SD卡壽命.

因為Raspberry Pi 3有Wifi, 所以接著就利用它來做為網路收音機.

先收集喜好的網路電台URL, 利用python寫一個script用來變換電台
推薦這個德國的音樂網站,有很多種類的音樂
http://stream.klassikradio.de/
用樣的利用python/bash寫一個web CGI介面, 便可以用瀏覽器控制電台變換
這樣也不需login到Raspberry Pi裡面操作

最後再加上先前利用8x8LED 加一個Arduino Micro做的顯示器
用來在開機時顯示Raspberry Pi的IP, 共兼做各種資訊的顯示
(8x8LED至少可以顯示英文字母+數字+常用符號)

2015-12-31

MK802 telegram + ESP8266 自動控制

由於ESP8266 本身俱有網路功能,只要有wifi 就能簡單建構起來。
這裡使用文字介面的 telegram-cli 加 esp8266(執行 telnetd service)。

利用 telegram-cli 當載具,可以接收來自地表各處給的指令(中國除外)、
向OS(Linux) 送出指令,介面由 python 組成(在我五月寫的 Telegram 機器人
那一篇有說明,用一台小小 的 MK802 (或Raspberry Pi)就可以達成。

MK802 到ESP8266 的介面也是藉由 python 來達成
ESP8266 用nodemcu 跑 telnetd service

與ESP8266 互動的部份:
espc = pexpect.spawn('telnet %s 23'%esp8266_IP)
--以下sendline() 內容可以改成任何指令
espc.sendline('gpio.mode(%s,gpio.OUTPUT)'%pin)
espc.expect('> ')
--取得執行後的資訊
espMSG=espc.before
print(espMSG)

ESP8266 執行 telnetd service 的部份:
s=net.createServer(net.TCP,180)
s:listen(23,function(c)
  function s_output(str)
    if(c~=nil) then c:send(str) end
  end
  node.output(s_output, 0)
  c:on("receive",function(c,l)
    node.input(l)
  end)
  c:on("disconnection",function(c)
    node.output(nil)
  end)
  print(" >> DE BV1AL <<")
end)
 
2015年要結束了,最後一天來灌點水! 

2015-05-22

大家來寫 Telegram 機器人

微軟把MSN玩死了,現在沒有MSN server可玩,以前根據 msnlib 寫的機器人都不能動了!
而 LINE 則是商業軟體,有人解出它的通訊模式, 寫成python 模組,就被LINE公司發函封口!
所以也不能寫 LINE 機器人。

還好有open source 的 Telegram !
Telegram 真是好物,因為它是open source 所以有了各種可能!
Telegram 跟LINE 的使用方式幾乎完全一樣,會用 LINE 的人幾乎立即可以上手。
Telegram 跟LINE 一樣有iOS, Android, Windows, MacOS 等版本, 但不同的是
Telegram 有Linux 版本!

Telegram 更有文字模式版本!就是 telegram-cli
git clone --recursive https://github.com/vysheng/tg.git
cd tg; ./configure --disable-liblua (用不到 lua 的話)
make
不過在make 之前你可能要先裝
libreadline-dev libconfig-dev libssl-dev libevent-dev 幾項libraries.
雖然它不是Telegram 團隊寫的,但因為 Telegram 是open source, 所以
telegram-cli 跟Telegram 完全相容!

網路上有一些以 lua 或 python 寫的 telegram-cli BOT, 也就是搭配 telegram-cli
可以自動收發資訊的外層程式,但是各有限制,所以我想想不如自己寫一個。

自己寫的好處是完全以容易寫、方便自己用,為目標,
只要利用 python 的 pexect 就能完成一個相當實用的 telegram-cli 機器人!

這裡來說一下重點,重點抓到後,細節可以千變萬化!

第一是
tg = pexpect.spawn('telegram-cli -k /path/server.pub -CNW')
tg.timeout = None
這樣會保持不跳開

第二是
tg.expect("> ")
這是 telegram-cli 在 standby 狀態時的提示符號,我們等它出現這個值,
然後來定義一些常數以便往下能使用。

第三是
while True:
進入無限迴圈,這樣便能處理「收、發」,這裡第一個要的是
tg.expect(">>> ")
這是有外來的資訊時會出現的指標,根據這個指標我們可以獲取兩段資訊。

在 ">>> " 出現之前的一段,是來訊的序號以及發訊人
Usend = tg.before.split()     #這是我們要的前一段
UID = Usend[-2]+'_'+Usend[-1] #這個可以得到對方的代號,用來送訊給對方

後一段就是資訊文,要再次利用系統提示號來區隔資訊文
tg.expect("> ")
在上面那個 ">>> " 之後,到這個 "> " 之前的一段,就是資訊文,或者就像是
我們在 LINE 聊天所送出的文字。
Umsg = tg.before
Ump = Umsg.split()
這裡故意分成一個未分割的 Umsg,以及一個分割的 Ump

如果 Umsg 的開頭是 "[photo" 或 "[image"
if Umsg.startswith('[photo') or Umsg.startswith('[image'):
我們的機器人就自動下載存檔(所以一開始 telegram-cli 的執行參數要有大寫 "N")
tg.sendline('load_photo %s'%Usend[-4])

上面只是一個例子,我們還可以定好指令字串,像收到對方送來 "get /path/file"
就可以區隔出他的指令是 "get" 也就是
if Ump[0] == 'get':
然後再區隔出後面非固定長度的的路徑+檔名
FILE = Umsg[4:].strip() 然後加上來訊對方的 UID
tg.sendline('send_file %s %s'%(UID,FILE))
來送出對方指定要抓取的檔名

也可以訂一個指令,像說
if Ump[0] == 'temp':
然後經由analog GPIO 去讀取 LM35 感溫晶體來回報目前溫度
tg.sendline('send_text %s %s'%(UID,temperature))

當然我們還可以訂一個自由指令,就是不事先訂好的字串,像說
if Ump[0] == 'cmd':
然後再來區隔出 'cmd ' 之後的任何字串
Ucmd = Umsg[4:].strip()
然後以 os.system 或 os.popen 來進行自由指令的執行
os.system('%s > /path/ucmd.txt'%Ucmd) 再由
tg.sendline('send_text %s /path/ucmd.txt'%UID)

這樣我們又有機器人可玩了!