Feeds:
文章
迴響

Archive for 2010 年 02 月

過年期間迷上 Youtube,寫了幾個關於 Youtube 的小工具,現在要介紹一個將 RMVB 依據每 10 分鐘分割成一個檔案的作法。為什麼寫這個程式呢?主要是因為 Youtube 限制上傳影片最多只能 10 分鐘,所以,我只好將影片依據這個長度進行分割在上傳,對於 AVI 我已經找到 Ultra Video Splitter 這套好用的工具,而 RMVB 我只發現 RealMedia Editor 和 Real Media 壓縮精靈2005 這兩套可用來分割,不過不支援依據時間長度切割。

收集一下資料發現,上述兩套工具都是使用 rmeditor.exe 這支程式來分割 RMVB,他的命令格式是

rmeditor.exe –i  input.rmvb –o output.rmvb –s 00:00:00:00.000 –e 00:00:10:00.000

所以我只要產生10分鐘的分割區間在呼叫程式就可以完成了。但是還有一個問題是,我需要影片總時間才能計算分割區,這個時候就需要使用 rma.exe (RealMedia Analyzer) 來取得影片資訊,如命令:

rma.exe –db input.rmvb

如此就可以獲得影片的總長度。以下就是上述概念的實現

# -*- coding: cp950 -*-
"""
@author Chui-Wen Chiu
@see http://www.ouyaoxiazai.com/article/24/311.html
"""
import os
import re
import string
import sys

S=1000
M=60*S
H=60*M
D=24*H

RMA_EXE = "rma.exe"
RMEDITOR_EXE = "rmeditor.exe"

def ts2str(ts):
    """
    timestamp 轉 DD:HH:MM:SS.mmm 格式
    """    
    d = ts /D
    t = ts %D

    h = t /H
    t = t %H

    m = t /M
    t = t %M

    s = t /S
    t = t %S

    
    return "%02d:%02d:%02d:%02d.%03d" % (d, h, m, s, t)

def split_ts(total_ts, clip_size=600000 ):
    M1 = clip_size
    seg = total_ts / M1
    seg_m = total_ts % M1
    split_seg = []
    for i in range(0, seg):
        bt = i * M1
        et = (i+1)*M1
        split_seg.append(
            {
                "sn": i,
                "bt": ts2str(bt),
                "et": ts2str(et)
            }
        )
        

    if seg_m > 0:
        bt = et
        et = total_ts
        split_seg.append(
            {
                "sn": i+1,
                "bt": ts2str(bt),
                "et": ts2str(et)
            }
        )        


    return split_seg

def extract_ts(fn):
    """
    萃取影片資訊
    """
    cmd = "%s -db "%s"" % (RMA_EXE, fn)
    x = os.popen( cmd ).read()
    v = re.search('(d*) ms', x).group(1)
    return string.atoi(v)

def split_rmvb(fn):
    """
    分割
    """
    ts = extract_ts(fn)
    seg_ts = split_ts(ts, 600 *S)
    name,ext=os.path.splitext(fn)
    for seg in seg_ts:
        ofn= "%s-clip%d%s" % (name, seg['sn'],ext)
        cmd = "%s -i "%s" -o "%s" -s %s -e %s" % (RMEDITOR_EXE, fn, ofn, seg['bt'], seg['et'])
        print cmd
        fo =open("test.bat", "w")
        fo.write(cmd)
        fo.close()
        
        os.system("test.bat")

if __name__ == '__main__' :
    fn = sys.argv[1]
    if os.path.exists(fn):
        split_rmvb(fn)
    else:
        print 'file not exists'

如此就可透過 split.py test.rmvb 執行 rmvb 分割。可以瘋狂的上傳 rmvb 到 Youtube 保存了  XDDD

Read Full Post »

從上次”[Python] 批次文件匯入 Google Sites”解決我文件檔案過多的問題,今天我想要解決另一個問題"Scrapbook",這是一個我非常喜歡的 Firefox 套件,我利用他收集了許多資料,我現在想要把資料轉匯到 Google Sites,因為匯出的資料會以條目名稱作為目錄名稱,並將本文內容存放在目錄下的 index.html。

所以我決定新增一個 docimport-scrapbook.py 負責這件事情,其實只是繼承 DocImport 然後改寫 doIt ,如下:

class DocsImportScrapbook(docimport.DocsImport):
  """
  批次匯入
  """
   
  def doIt(self, src, parent_name = None):
    print src
    parent = None
    log = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    h = logging.FileHandler('fail.log')
    h.setFormatter(formatter)
    log.addHandler(h)
    log.setLevel(logging.INFO)

    if not parent_name is None:
      # 取得上層 feed
      feed = self.client.GetContentFeed('https://sites.google.com/feeds/content/%s/%s?path=%s' %(self.dn, self.sn, parent_name))
      if len(feed.entry)>0:
        parent = feed.entry[0]
        

    for f in glob.glob(src + '\*'):      
        print f
        fn = f.split('\')[-1]        
        name = fn.split('.')[0]
        try:
          f = f+'\index.html'
          content=codecs.open(f, 'r', 'cp950').read()
        except UnicodeDecodeError, error:
          try:
            content=codecs.open(f, 'r', 'utf-8').read()            
          except UnicodeDecodeError, error:            
            print '%s =>open file fail, encode invalid' % name
            logl.info(name)
            continue
          
        self._import( name.decode('cp950'), ('<pre>%s</pre>' %content), parent )

執行結果:

image

 

又輕鬆解決我一個問題 ^^

Read Full Post »