網頁

2016年2月4日 星期四

VLC 之 http

vlc.exe --intf="http" --http-host 0.0.0.0 --http-port 8080 --http-password 1234

http://localhost:8080/requests/playlist.xml

http://localhost:8080/requests/status.xml?command=in_play&input=rtsp://169.254.1.168:554/live2.sdp

http://localhost:8080/requests/status.xml?command=snapshot

http://localhost:8080/requests/status.xml?command=pl_stop

http://localhost:8080/requests/vlm_cmd.xml?command=new ch1 broadcast enabled
http://localhost:8080/requests/vlm_cmd.xml?command=setup ch1 input rtsp://169.254.1.168:554/live2.sdp
http://localhost:8080/requests/vlm_cmd.xml?command=control ch1 play
http://localhost:8080/requests/vlm_cmd.xml?command=control ch1 stop

share/lua/intf/modules/httprequests.lua
processcommands = function ()
in_play
addsubtitle
in_enqueue
pl_play
pl_pause
pl_forcepause
pl_forceresume
pl_stop
pl_next
pl_previous
pl_delete
pl_empty
pl_sort
pl_loop
pl_repeat
pl_sd
fullscreen
snapshot
volume
seek
key
audiodelay
rate
subdelay
aspectratio
preamp
equalizer
enableeq
setpreset
title
chapter
audio_track
video_track
subtitle_track


2016年1月29日 星期五

unix shell command

for i in `find .. -name '*.c' -print`
> do
> echo $i
> grep "vlm_ExecuteCommand" $i
> if [ ${?} == "0" ]
> then
> read -p $i any
> fi
> done

aaa.sh >a.out 2>&1

tail -f a.out

常用 vi 命令
移動游標 h, j, k, l
輸入 i, a
連接兩行 J
刪除 dd
拷貝 yy
貼上 p
紀錄位置 ma
跳到先前紀錄的位置 `a
暫時跳到 :!sh
不存檔離開 :q!
存檔離開 :wq
自動加入內縮:set ai
取消自動加入內縮:set noai

使用UTF-8編碼,且有 BOM
~/.vimrc
set bomb
set fileencoding=utf-8

VLC CLI snapshot command 程式追蹤

share/lua/modules/common.lua
function snapshot()
    local vout = vlc.object.vout()
    if not vout then return end
    vlc.var.set(vout,"video-snapshot",nil)
end

以下是啟動時建立物件
modules/lua/intf.c
static int Start_LuaIntf( vlc_object_t *p_this, const char *name )
-> luaopen_object( L );
-> luaopen_vlm( L );

modules/lua/libs/objects.c
static const luaL_Reg vlclua_object_reg[] = {
    { "input", vlclua_get_input },
    { "playlist", vlclua_get_playlist },
    { "libvlc", vlclua_get_libvlc },
    { "find", vlclua_object_find },
    { "vout", vlclua_get_vout},
    { "aout", vlclua_get_aout},
    { NULL, NULL }
};
void luaopen_object( lua_State *L )
{
    lua_newtable( L );
    luaL_register( L, NULL, vlclua_object_reg );
    lua_setfield( L, -2, "object" );
}

src/video_output/video_output.c
vout_thread_t *vout_Request(vlc_object_t *object, const vout_configuration_t *cfg)
-> VoutCreate(object, cfg);
static vout_thread_t *VoutCreate(vlc_object_t *object, const vout_configuration_t *cfg)
-> vout_IntfInit(vout);
在此宣告出 SnapshotCallback
void vout_IntfInit( vout_thread_t *p_vout )
-> var_Create( p_vout, "video-snapshot", VLC_VAR_VOID | VLC_VAR_ISCOMMAND );
-> var_Change( p_vout, "video-snapshot", VLC_VAR_SETTEXT, &text, NULL );
-> var_AddCallback( p_vout, "video-snapshot", SnapshotCallback, NULL );

以下是執行 snapshot 命令
./modules/lua/libs/variables.c
{ "trigger_callback", vlclua_trigger_callback },
{ "set", vlclua_var_set },
static int vlclua_var_set( lua_State *L )
-> var_Set( *pp_obj, psz_var, val );
static int vlclua_trigger_callback( lua_State *L )
-> var_TriggerCallback( *pp_obj, psz_var );

很多地方都使用 var_TriggerCallback 執行 snapshot
./lib/video.c
-> var_TriggerCallback( p_vout, "video-snapshot" );
./modules/control/oldrc.c
-> psz_variable = "video-snapshot";
-> var_TriggerCallback( p_vout, psz_variable );
./modules/control/hotkeys.c
-> case ACTIONID_SNAPSHOT:
-> var_TriggerCallback( p_vout, "video-snapshot" );

./src/misc/variables.c
var_TriggerCallback -> TriggerCallback
var_Set -> var_SetChecked -> TriggerCallback

src/video_output/vout_intf.c
static int SnapshotCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data )
SnapshotCallback -> VoutSaveSnapshot -> vout_snapshot_SaveImage
SnapshotCallback -> VoutSaveSnapshot -> VoutOsdSnapshot
msg_Dbg( p_vout, "snapshot taken (%s)", psz_filename );


VLC 之 VLM command 追蹤

share/lua/intf/cli.lua
function client_command( client )
-> call_command(cmd,client,arg) 呼叫 CLI commands
-> call_vlm_command(cmd,client,arg) 呼叫 VLM command
function call_vlm_command(cmd,client,arg)
-> vlm:execute_command( cmd )

modules/lua/intf.c
static int Start_LuaIntf( vlc_object_t *p_this, const char *name )
-> luaopen_vlm( L );

modules/lua/libs/vlm.c
static const luaL_Reg vlclua_vlm_reg[] = {
    { "execute_command", vlclua_vlm_execute_command },
    { NULL, NULL }
};
void luaopen_vlm( lua_State *L )
{
    lua_pushcfunction( L, vlclua_vlm_new );
    lua_setfield( L, -2, "vlm" );
}
static int vlclua_vlm_new( lua_State *L )
-> luaL_register( L, NULL, vlclua_vlm_reg );
static int vlclua_vlm_execute_command( lua_State *L )
-> i_ret = vlm_ExecuteCommand( *pp_vlm, psz_command, &message );

src/input/vlm.c
int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command, vlm_message_t **pp_message)
-> i_result = ExecuteCommand( p_vlm, psz_command, pp_message );

src/input/vlmshell.c
int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, vlm_message_t **pp_message )
del -> ExecuteDel
show -> ExecuteShow
help -> ExecuteHelp
control -> ExecuteControl
save -> ExecuteSave
export -> ExecuteExport
load -> ExecuteLoad
new -> ExecuteNew
setup -> ExecuteSetup
static int ExecuteControl( vlm_t *p_vlm, const char *psz_name, const int i_arg, char ** ppsz_arg, vlm_message_t **pp_status )
play -> vlm_ControlInternal
stop -> vlm_ControlInternal
pause -> vlm_ControlInternal
seek -> vlm_ControlInternal



VLC 之 lua 程式除錯追蹤

vlc.msg.dbg("debug message")
vlc.msg.err("error message")

modules/lua/intf.c
static int Start_LuaIntf( vlc_object_t *p_this, const char *name )
-> luaopen_msg( L );

modules/lua/libs/messages.c
static const luaL_Reg vlclua_msg_reg[] = {
    { "dbg", vlclua_msg_dbg },
    { "warn", vlclua_msg_warn },
    { "err", vlclua_msg_err },
    { "info", vlclua_msg_info },
    { NULL, NULL }
};
void luaopen_msg( lua_State *L )
{
    lua_newtable( L );
    luaL_register( L, NULL, vlclua_msg_reg );
    lua_setfield( L, -2, "msg" );
}
static int vlclua_msg_err( lua_State *L )
{
    int i_top = lua_gettop( L );
    vlc_object_t *p_this = vlclua_get_this( L );
    int i;
    for( i = 1; i <= i_top; i++ )
        msg_Err( p_this, "%s", luaL_checkstring( L, i ) );
    return 0;
}

主要除錯資料輸出
vlc_object_t *p_this = vlclua_get_this( L );
msg_Err( p_this, "error message");

2016年1月27日 星期三

VLC command

vlc.exe --help
vlc.exe --intf="telnet"
vlc.exe --intf="http"
vlc.exe --intf="dummy"

除圖形介面外,額外使用 telnet 介面
vlc.exe --extraintf="telnet"

產生訊息
-vvv

產生訊息於檔案
--verbose=2 --file-logging --logfile=vlc-log.txt

網路 caching 5秒
--network-caching=5000

vlc.exe --intf="telnet" --telnet-host="0.0.0.0" --telnet-port="4212" --telnet-password="1234" --verbose=2 --file-logging --logfile=vlc-log.txt

vlc.exe --extraintf="http" --http-host="127.0.0.1:9090"

使用本機的 webcam
vlc.exe -vvv dshow:// --dshow-vdev="Integrated Camera"

螢幕錄影
vlc.exe screen:// --screen-fps=24 --screen-follow-mouse --screen-mouse-image="Mouse_pointer_small.png" --sout "#transcode{vcodec=h264,venc=x264{scenecut=100,bframes=0,keyint=10},vb=1024,scale=1,vfilter=croppadd{cropleft=0,croptop=0,cropright=0,cropbottom=0}}:duplicate{dst=std{access=file,mux=mp4,dst="R:\Temp\aaa.mp4"}}"

不顯示影像
vlc.exe rtsp://169.254.1.168:554/live2.sdp --sout "#duplicate{dst=display,select='novideo'}" --verbose=2 --file-logging --logfile=vlc-log.txt

不顯示控制介面,使用telnet控制,並且延遲5秒
vlc.exe rtsp://169.254.1.168:554/live2.sdp --network-caching=5000 --vout dummy --intf telnet --telnet-host="0.0.0.0" --telnet-port="4212" --telnet-password="1234" --verbose=2 --file-logging --logfile=vlc-log.txt

顯示時間
vlc.exe rtsp://169.254.1.168:554/live2.sdp --sub-source "marq{marquee=%Y/%m/%d %H:%M:%S,x=10,y=50}"
vlc.exe rtsp://169.254.1.168:554/live2.sdp --sub-filter "marq{marquee=%Y/%m/%d %H:%M:%S,position=6}"

vlc.exe rtsp://169.254.1.168:554/live2.sdp --sout file/avi:"R:\temp\aaa.avi"
vlc.exe rtsp://169.254.1.168:554/live2.sdp --sout="#std{access=file,mux=avi,dst='R:\temp\aaa.avi'}"
vlc.exe rtsp://169.254.1.168:554/live2.sdp --intf dummy --sout file/avi:"R:\temp\aaa.avi"
vlc.exe rtsp://169.254.1.168:554/live2.sdp --snapshot-path="R:\temp" --snapshot-prefix="aaa" --snapshot-format=jpg --intf="telnet" --telnet-host="0.0.0.0" --telnet-port="4212" --telnet-password="1234" --sout file/avi:"R:\temp\aaa.avi" -vvv --file-logging --logfile=vlc-log.txt

VLC 設定檔

C:\Users\UserName\AppData\Roaming\vlc\vlcrc


new ch1 broadcast enabled
setup ch1 input screen:// :screen-fps=24 :screen-follow-mouse 
setup ch1 input rtsp://169.254.1.168:554/live2.sdp
setup ch1 output #file{mux=ps,dst='R:\temp\aaa.ps'}
setup ch1 output #file{mux=avi,dst='R:\temp\aaa.avi'}
control ch1 play
snapshot
control ch1 stop

shutdown

人力發電機 & 電表

  • 手搖充電器

材料使用吸管,磁鐵,漆包線,二極體

  • 轉動充電器




材料使用無刷馬達,二極體,3D列印轉軸


  • 充電&LED燈

材料使用鎳氫電池, HT7733A電壓轉換


  • 功率電表&電壓電流分配器



  • 手搖充電器 測試

測試結果:450mJ-分,平均5mA
推測 2700mA-1.2V 鎳氫電池,約430小時充飽

  • 轉動充電器 測試

測試結果:50J-分,平均450mA
推測 2700mA-1.2V 鎳氫電池,約4小時充飽