利用批處理文件和 vbs 腳本實現網站視頻自動錄制
現在電視台基本上都有了自己的門戶網站,我們可以充分利用網絡的優勢來擴大本地電視台的影響。事實上,將本地電視台的每日的王牌節目掛在網站上的做法已經成為建立電視台網站的必要組成步驟之一了。但隨之而來的問題是:每天定時需要的手工錄制過程,將給管理者帶來極大的不便。在 windows 定時任務的基礎上,將批處理程序與腳本程序有機的集合,就可以有效地解決這一問題。
1 :建立壓碼任務
我們將使用一台帶有視頻采集卡的電腦來完成壓碼過程。雖然壓碼不是本文的重點,但還是有必要交代一下。主要就是使用 helix producer plus9 建立一個壓碼參數文件,事實上它只是一個帶有 rpjf 後綴的 xml 文件(圖 1 )。需要注意的是,音頻輸入選項有線路輸入與 microphone 輸入兩種,這需要與實際的接入線路相吻合;另外,不必選擇 2 pass vedio encoding 選項,選擇它除了顯示一個 warning 外不會有任何效果;再者,因為現階段絕大多數的網絡接入模式為撥號和 dsl ,所以只需要生成 56k 和 384k 碼率的視頻文件;最後,錄制完成的視頻文件,其名稱最好用日期來標識,比如: 20060301.rm 。
<?xml version="1.0" encoding="UTF-8"?>
<job xmlns="http://ns.real.com/tools/job.1.0.1">
<enableTwoPass type="bool">false</enableTwoPass>
<clipInfo>
<entry>
<name>Author</name>
<value type="string">ZSTV</value>
</entry>
<entry>
<name>Copyright</name>
<value type="string">(c) ZSTV2006 </value>
</entry>
<entry>
<name>Keywords</name>
<value type="string">ZSNews[2006-03-21]</value>
</entry>
<entry>
<name>Title</name>
<value type="string">ZSNews[2006-03-21]</value>
</entry>
</clipInfo>
<input>
<captureInput>
<audioDeviceID type="string">Intel(r) Integrated Audio</audioDeviceID>
....................................
我們可以建立一個名為 shixian.bat 的批處理文件來的調用上面所示的參數文件,內部具體如下:
producer -j "d:\shixian\shixian.rpjf" -daw -lc "e,i"
默認的錄制過程會實時監控音頻變化,並將它記錄到一個叫 producer.log 的文件之中,但是產生的 wanging 記錄很多,很快就使 log 文件變得巨大而且可能引起錄制過程的意外中斷,所以我們可以使用 -daw 參數關閉音頻監視,再用 lc “e,i” 指明只記錄錯誤和信息。這樣做之後,錄制過程就比較穩定了。
只要在計劃中添加每日執行 shixian.bat 文件的任務,我們就會每天得到一個相同文件屬性和名稱的 rm 文件。在這裡將每天產生一個帶有 2006-03-21 屬性的、名為 20060321.rm 文件。聽起來很拗口,更糟糕的是這並沒有減輕管理者的工作,因為他不得不每天打開服務器為其改名稱。而且即便有幸雇傭了一名勤奮的管理員(他不介意每天做這樣重復的事情),但他還是沒辦法更改文件中顯示日期的屬性,在這錄制過程中已經決定了。除非 …….
2 :建立修改壓碼參數文件的任務
原理很簡單:每天更新壓碼參數文件中與日期相關的 xml 字段。在這個例子裡是文件顯示日期的屬性和文件名。 下面就是用於更新日期字段的腳本代碼:
dim regOR
set regOR=new regexp ‘ 建立一個正則表達式對象
regOR.ignorecase=True ‘ 忽略大小寫
regOR.global=True ‘ 搜索應用於整個字符串
regOR.pattern="^([0-9]{1})$" ‘ 建立搜索模式為單數字表達式
dim mytime
mytime=date ‘ 用 date 函數達到系統日期,並賦值給 mydate
yy=year(mytime) ‘ 提取系統日期中的年份
mm=month(mytime) ‘ 提取系統日期中的月份
dd=day(mytime) ‘ 提取系統日期中的日期
if regOR.test(mm) then ‘ 檢測月份是否為單數字(一月到九月)
mm=regOR.replace(mm,"0$1") ‘ 如果是,則在月份前添加 0 使其成為兩個數字
end if
if regOR.test(dd) then ‘ 檢測日期是否為單數字(一日到九日)
dd=regOR.replace(dd,"0$1") ‘ 如果是,則在日期前添加 0 使其成為兩個數字
end if
mytime=yy & "-" & mm & "-" & dd ‘ 合並年月日為 ”yy-mm-dd” 形式
dest=yy & mm & dd ‘ 合並年月日為 ”yymmdd” 形式
pattern1="(.*[^0-9])([0-9]{4}\-[0-9]{2}\-[0-9]{2})([^0-9].*)"
‘ 設定模式變量 pattern1 為 ”%d%d%d %d- %d %d -%d %d”
pattern2="(.*[^0-9])([0-9]{8})([^0-9].*)" ‘ 設定模式變量 pattern2 為 8 個連續數字
regOR.pattern=pattern1 ‘ 建立搜索模式為 pattern1
dim tempstring
Set fso = CreateObject("Scripting.FileSystemObject") ‘ 建立系統文件對象
Set f = fso.CreateTextFile("d:\shixian\temp.txt", True) ‘ 新建名為 temp 的文本文件
Set fr = fso.GetFile("d:\shixian\shixian.rpjf") ‘ 得到編碼參數文件 shixian.rpjf
Set ts = fr.OpenAsTextStream(1,-2) ‘ 將參數文件以只讀文本形式打開
do until ts.AtEndOfStream ‘ 建立循環,直到參數文件讀取完畢
tempstring=ts.readline ‘ 以行為單位讀取參數文件
if regOR.test(tempstring) then ‘ 搜索改行參數是否存在日期字段
tempstring=regOR.replace(tempstring,"$1" & mytime & "$3") ‘ 如存在,則更新
end if
regOR.pattern=pattern2 ‘ 建立搜索模式為 pattern2
if regOR.test(tempstring) then ‘ 搜索改行參數是否存在日期字段
tempstring=regOR.replace(tempstring,"$1" & dest & "$3") ‘ 如存在,則更新
end if
regOR.pattern=pattern1 ‘ 重新建立搜索模式為 pattern1
f.writeline(tempstring) ‘ 將更新後的數據寫入 temp.txt 文件
loop
ts.close ‘以下是關閉和注銷各個對象
f.close
set regOR=nothing
set ts=nothing
set fr=nothing
set f=nothing
set fso=nothing
要說明的是為什麼要在單數字的月份和日期前加 0 。打個比方比較容易說明:如果不加 0 ,那麼對於一個名為 2006111.rm 的文件,它究竟是指 2006 年 1 月 11 日還是 2006 年 11 月 1 日呢?加 0 後變成 20060111.rm 就一目了然了,是前者。
以上這段腳本代碼的具體功能是將參數文件中的數據以行為單位導入到一個臨時的文本文件中,實時監視與時間相關的 xml 字段並加以更新,最後在生成一個 temp.txt 的文件。之後我們要做的無非就是用一個批處理文件調用腳本,再刪除舊的參數文件,最後將 temp.txt 重命名為參數文件。
這就是 update.bat 批處理文件中的代碼:
@echo off
d:\shixian\update.vbs
if exist "d:\shixian\shixian.rpjf" del "d:\shixian\shixian.rpjf"
if exist "d:\shixian\temp.txt" rename d:\shixian\temp.txt shixian.rpjf
和第一節中一樣,還是要將這個 update.bat 的批處理文件添加到計劃與任務中,以便每日定時啟動。
3 :建立自動傳輸任務
為了確保穩定,通常壓碼服務器與網站服務器是分離的,這就需要我們每日將錄制的視頻文件傳輸到網站服務器上。批處理文件中的 ftp 命令可以完美的實現這一功能。
以下就是 transfer.bat 批處理中的代碼:
@echo off
ftp -s:media.txt
if exist "d:\shixian\shixian20060321.rm" del d:\shixian\shixian20060321.rm
考慮到 SCSI 硬盤驚人的價格,壓碼服務器的硬盤空間不必太大,最後一行的作用就是刪除壓碼服務器中的視頻文件,以節省空間。 Media.txt 是一個 ftp 參數文件,其中記錄了 ftp 登陸服務器的名稱、用戶名、密碼和相關的操作,具體形式如下:
open / 服務器名稱或 IP 地址 /
/ 用戶名 /
/ 用戶密碼 /
put / 要傳輸的文件名 /
quit
很明顯,以上的各段代碼中不乏需要更新的日期文字表達式。同樣的道理,我們也需要使用一個類似的更新腳本,具體代碼就不重復了。
4 :一些改進的意見
1 :使用 media player 也可實現壓碼的功能。
2 :在更新腳本中,用在聲明和注銷對象上的代碼有好幾行,如果使用 perl 可以大為簡化。因為是 perl 提供了一系列操作符號來實現正則表達式的功能,而事實上 perl 就是為了處理文本而生的。
open(RPJF,"<c:/code/10161.rpjf") or die("can not open because of $!\n");
open(TEMP,">c:/code/temp.txt") or die("can not open because of $!\n");
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime();
$mday=sprintf("%.2d",$mday);
$mon=sprintf("%.2d",$mon+1);
$year+=1900;
$timerF="$year"."$mon"."$mday";
$timerS="$year"."-"."$mon"."-"."$mday";
while(<RPJF>){
chomp();
$_=~s/(.*)([0-9]{8})(.*)/$1$timerF$3/;
$_=~s/(.*)([0-9]{4}\-[0-9]{2}\-[0-9]{2})(.*)/$1$timerS$3/;
print TEMP "$_\n";
}
close(RPJF);
close(TEMP);
3 :使用磁盤映射能夠更加方便的實現文件的傳輸,不過需要考慮安全問題。