CSS Styles

Monday, March 13, 2017

【DOS】VBS Extension

相對於 *nix, DOS 功能簡陋, 拼拼湊湊勉強堪用, 進階處理著實捉襟見肘, 令人苦惱。 以數值計算為例, 僅提供 32-bit 有號整數, 不支援浮點; 還好 DOS 可以輕易呼叫 VBS (Visual Basic Script), 讓缺憾得以彌補。

以下短短不起眼指令, 讓 DOS 盡情揮灑 VBS 的能力:

eval.vbs 檔案內容

 WScript.Echo Eval(WScript.Arguments.Item(0))

DOS Prompt 下呼叫 eval.vbs

 cscript eval.vbs "Sin(1)"
 0.841470984807897


DOS 批次檔中調用 eval.vbs

 for /F %%i in ('cscript eval.vbs "Sin(1)"') do set r=%%i
r = returned VBS result

Friday, February 24, 2017

【DOS】String - Lowercase

lowercase 不像 uppercase 擁有美麗巧合, 無法與 find 或其它指令擦出火花, 只能土法練鋼。 DOS 基本指令中皆未含字碼轉換能力, 所以最快的方法就是查表法。

:LOWERCASE
 set r=
 set "i=%~1"
 set tab=AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
:LRC1
 if "%i%" == "" exit /b
 set c=%i:~0,1%
 if "%c%" GEQ "A" if "%c%" LEQ "Z" call set c=%%tab:*%c%=%%& set c=%c:~0,1%
 set r=%r%%c%
 set i=%i:~1%
 goto :LRC1
r = returned uppercase string

Wednesday, February 1, 2017

【Media】QSV2FLV Time Code Fix

愛奇藝影片緩存之副檔名為 QSV, 乃愛奇藝特有的封裝格式, 愛奇藝萬能播放器自然直接支援, 但鑑於通用性與系統安全, 無安裝該播放器之念。

網路上雖可尋獲 QSV 轉 FLV 的應用程式, 轉換過的檔案可用一般播放器回放, 卻存在時間碼 (timecode) 錯亂的情形, 造成影片搜尋困難, 無法驟跳至任意點觀賞。 欲修正此問題, 得重新封裝視訊與音訊, 並提供正確的時間資訊。

分析 FLV 的內容, 視訊是 H264, 音訊是 AAC, 皆為 MPEG4 首選格式, 很適合封裝成 MKV 檔案。 使用 MKVToolNix 中 mkvmerge 工具, 遞予正確的 frame rate, 即可讓 MKV 擁正確時間碼。 以 NTSC 影片『浪漫醫生金師傅』為例, 以下指令可達此目的。

 mkvmerge --default-duration 0:30000/1001p
          --default-duration 1:22054/1024p -o OUTPUT.MKV INPUT.FLV

Tuesday, January 17, 2017

【DOS】String - Uppercase

網路上最佳解法, 據聞為 Mark Tattersall 的點子, 頗具創意, 藉 find 指令錯誤訊息之特性, 很妙的小技巧, 但 lowercase 就沒這類的捷徑了。

:UPPERCASE
 for /F "tokens=2 delims=-" %%i in ('find "" "%~1" 2^>^&1') do set "r=%%i"
 set "r=%r:~1%"
 exit /b
r = returned uppercase string

看似便捷的方案, 隱含兩項限制:
1. 不得存在相同字串的檔案, 否則非但無錯誤輸出, 反倒會去處理該檔之內容。
2. 字串不得含減號, 不然會被視為分隔字元, 無法取得完整字串。

為免除上述限制, 可在字串前加上檔名所不允許之特殊字元"冒號", 且不使用 for 粹取字串。

:UPPERCASE
 for /F "tokens=*" %%i in ('find "" ":%~1" 2^>^&1') do set "r=%%i"
:UPC1
 if not "%r:~0,1%" == ":" set "r=%r:~1%"& goto :UPC1
 set "r=%r:~1%"
 exit /b
r = returned uppercase string

粹取字串的另一個方法是: 直接將不要的訊息移除, 利用字串取代可輕易為之。

:UPPERCASE
 for /F "tokens=*" %%i in ('find "" ":%~1" 2^>^&1') do set "r=%%i"
 for /F "tokens=*" %%i in ('find "" "" 2^>^&1') do set "e=%%i"
 call set "r=%%r:%e%:=%%"
 exit /b
r = returned uppercase string