2012年04月24日

【CentOS6に動画環境】mplayerのinstallではまりましたよ!

 予告通り、前々稿の「【はまりました】CentOS6のGUI起動不可に悩む。で「CUI起動→GUI」に変更」の原因の可能性がある問題のパッケージに依存関係があるので、要注意の作業である。もし、ここで書いたものを実行したいなら、最低でも事前に/etc 以下をtar程度でも構わないので、バックアップを取ってからにして欲しい。少なくとも/etc/X11/以下に変更が加えられる虞れがあるからである。

続きを読む
posted by Mire at 15:15 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2012年04月23日

【CentOS6に動画環境】ffmpegのinstall

 ffmpegはコマンドラインで、動画ファイルを指定し、他の形式のものに変換したり出来るアプリであり、以前、Windows環境でのAVCHD動画再生で紹介したMPCのモジュールとしても使われていたものでもある。CentOS6の様に動画環境が貧弱なOSで非対応動画を変換して閲覧するには便利なものと思うので今回インストールして試た。
 また、前稿で、余計なパッケージ導入がGUI起動不能を招いたことを述べたが、これは前稿の障害原因を明らかにする為の前座の記事でもあることを最初に触れておく。

 CentOS6はRedhat Enterprise Linux6という、企業でのサーバ利用を主なターゲットとしてパッケージセットを形成したものである為だろうが、他のLinuxディストリビューションに比べ、今のWindowsPCで一般的な動画ファイルすら、標準では再生出来ないし、今では、何故かNTFSへのアクセスすら出来ないので、無理にでもWindowsPC環境でやっていたことを実現したいなら、他のリポジトリを導入、接続して望みのパッケージをinstallするか、以下で説明する様に必要なrpmファイルをネット検索し手元にダウンロードしyumまたはrpmコマンドでinstallすることになってしまう。

 尚、当方の場合、サーバ利用指向の為、CentOS6を端末用途でも選択しているが、あまり苦労したくない人が使うLinuxディストリビューションとしては、Ubuntuを選択することをお奨めしておく。デスクトップの高機能化を除いてはとても良いLinuxディストリビューションで端末用途での自由度は高くお奨めである。でも、導入PCとの相性等の理由でCentOS6を選択せざるを得ない場合には、まぁ、この記事は読んでおいても損はないのかもしれない。

 それでは、本題のffmpegのinstallについて先に進ませて頂く。
続きを読む
posted by Mire at 22:40 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2012年03月08日

【Android】NocoRo α版でホークス戦を生観戦

 以前ホークス戦のネット放送をこのブログでとりあげたことがあったが、何時の間にやら有償サービスに鞍替えしてしまい興味が失せてしまっていた。昨年は棚からぼた餅的にどなたかがプライベードでなさっている放送をKeyHoleTVで観たことがあったが、出先で楽しんだことはなかった。
Android NocoRo α版での2012.03.07プロ野球ホークス対タイガース戦のニコニコ生放送の全画面受信(Acer ICONIA TAB A500) しかし、数ヶ月前にAndroid開発の学習目的で購入したTablet端末で、何とか欲望を満たすことが出来ないものかと、このオープン戦シーズンに探して試たところ、今年はニコニコ生放送で、横浜DeNAベイスターズ、楽天ゴールデンイーグルス、福岡ソフトバンクホークスの3球団主催の全試合が完全生中継されるとのことである。まぁ、ニコニコ生放送の場合、ご存知の通り、有償のプレミアム会員優先の為、時々退席を求められることはあるが、出先での空き時間に短時間確認したい場合程度の利用であれば充分活用出来そうである。
続きを読む
posted by Mire at 02:17 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2011年08月17日

DVD_Label0.0.24 リリース(管理機能付)

 色々あって、間を開けてしまったが、管理機能付の最初の正式版としてDVD_Label0.0.24を先程リリースした。既にお使いの方は、今後はこちらをご利用をお奨めする。恐らく、文字化け等の基本動作面でも漸次修正が加えられて来ているし、何よりもSQLite3形式のDBファイルに、タイトル情報を記録蓄積し、検索やTSVファイル書出し機能により、他のアプリでのデータ活用が可能になっているからだ。

 ダウンロードは、従前通り「DVD-VIDEO TITLES LABELER - DVD_Label」の使い方(導入編)を玄関とし、Download Pageからである。ドキュメント修正は追い付いていないが、今後少しずつ手を入れて行くつもりでいるので、お待ち頂きたい。
続きを読む
タグ:dvd_label DVD-VR
posted by Mire at 01:11 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2011年08月02日

DVD_Label0.0.22 リリース

 昨日予告のDVD_Labelの改善版をリリースします。DVD_Label0.0.21同様、RC扱いです。データ管理機能以外では、1年前の版よりは昨日掲載のdiffを見ると安定させて来ている様なので、その範囲であれば、前版をUpdateしても特段問題はないと思うが、今後継続的に使う場合、DB設計に変更が伴なった場合に、移行という課題を抱える可能性がある点が、RCとしている理由なので、試用と言う観点でご利用頂き、問題があればコメント頂ければ有難い。

DVD_Label 0.0.22 build 2011-08-02_21.07JST データ管理機能付

 今回の変更は、コマンドプロンプトから、他のディレクトリをカレントディレクトリとして実行した場合に、データベースファイルの位置が、そのカレントディレクトリになってしまう課題に対する対処として、既定として、ツールをインストールしたディレクトリに固定的に作成利用される様にしたので、それでほぼ、この課題はFixed出来たと思う。
 しかし、例えば「C:\」や「C:\Program Files」直下だった場合の書込権限不足となる場所にインストールした場合には、エラーとなって返って来るので、dvd_label.confで設定出来る様にした。
 でもその場合にも、実在しないフォルダを設定した場合にもエラーとなるってしまう。そこで、エラー発生時には、その旨メッセージを表示し対処を促す様にした。


続きを読む
posted by Mire at 22:53 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2011年08月01日

DVD_Label0.0.21 データ管理機能付のdiff掲載

よくよく見て試ると、前公開バージョンから1年も放置していたことが判った。流石に久しぶりに修正を試ようと、結構忘れてしまっていて、てめーのコードを読み理解するのに苦労してしまった。そこで、今回のコードには改変していない所にもコメントを追加修正したり、不要なコードの除去を行なったので、この際、前公開の版との間の差分ファイルをここに掲載し、変更箇所の履歴としておこうと思う。
 尚、既に判っていることなので、ここに書いておくが、この版迄は、コマンドプロンプトでdvd_label.exeやdvd_label.pyを別ディレクトリをカレントとして実行すると、データベースファイルがそのカレントディレクトリに作成されてしまう。この仕様は作成者にとってテストには良いが、配布されたユーザにとっては嵌まると嫌なものなので明日、修正版を出す予定でいる。その旨ご承知置き願いたい。

 さて、以下が、そのdiffコマンドで作成した差分ファイルであるが、今後の為、適宜、註記を追記して行く予定でいる。見たことがない人は、'diff -du 前ファイル 現ファイル'の様に叩いて頂けば同じものが得られるが、Windowsには標準ではないので、別途入手導入が必要でとなる。見方は、マイナスは前ファイルのみにある行、プラスは現ファイルのみにある行として読んで行けばよい。共通の前後行が位置情報として書出されているのでdiffファイルだけでも概ね変更内容を把握出来るが必要により人は前ファイル と 現ファイル参照することもある。



--- DVD_Label_0.0.17_2009-07-28b_23.58JST\dvd_label.py Mon Aug 01 11:11:04 2011
+++ DVD_Label_0.0.21_2011-07-31_21.52JST\dvd_label.py Sun Jul 31 21:43:04 2011
@@ -1,28 +1,44 @@
-#!c:\\Python26\\/python.exe
+#!c:\\Python26\\python.exe
# -*- coding: UTF8 -*-
# ※ Windows の場合1行目はdummyです。

-
#####################################################################
#表示系個別関数
def dsp_adv():
- from sys import stdout
- from codecs import getwriter
- stdout = getwriter('utf_8')(stdout)
- print u"\n########################################################################"
- print u"# System NAME : DVD-VIDEO TITLES LABELER Ver.0.0.17 2009-07-28b #"
- print u"# Copyright : 2009- Mire(まあいいやあ) http://pythonlife.seesaa.net/ #"
- #print u"# Licence : GPLに基づく利用と再配布をお願いします。 #"
- #print u"# Requirement : Python2.6 or later 但しWondows,Shift_JISでの決打ちあり #"
- #print u"# HowToRun : Type 'python dvd_label.py' on windows command prompt. #"
- print u"########################################################################"
+ print u"\n######################################################################"
+ print u"# System NAME: DVD-VIDEO TITLES LABELER Ver.0.0.21alpha 2011-07-31 #"
+ print u"# Copyright : 2009- Mire(まあいいやあ) in Japan #"
+ print u"# Contact : http://pythonlife.seesaa.net/article/124770100.html #"
+# print u"# Licence : GPLv3(意味:そのままの利用再配布自由+ソース公開義務) #"
+# print u"# http://www.gnu.org/copyleft/gpl.html #"
+# print u"# http://www.opensource.jp/gpl/gpl.ja.html #"
+# print u"# http://www.gnu.org/licenses/rms-why-gplv3.ja.html #"
+# print u"# Requirement: Python2.6 or later 但しWondows,Shift_JISでの決打ちあり#"
+# print u"# HowToRun : Type 'python dvd_label.py' on windows command prompt. #"
+ print u"######################################################################"
+
+
+__author__ = "Mire in Japan"
+__version__ = '0.0.21alpha'
+__copyright__ = 'Copyright (c) 2011 Mire'
+__license__ = 'GPL'
+__url__ = 'http://pythonlife.up.seesaa.net/download/DVD_LABEL.html'


def dsp_history():
print u"\n####################### HISTORY OF THE SOFTWARE #######################"
print u"# #"
+ print u"# 0.0.21 2011-07-31 「R」でDB登録に、ソースのCleanupとコメント付記 #"
+ print u"# 登録済番組には右端にディスク番号を追記表示 #"
+ print u"# #"
+ print u"# 0.0.20 2011-02-08 dsp_disks()でディスクタイトルの一覧表示を暫定追加#"
+ print u"# #"
+ print u"# 0.0.19 2011-02-08 items.has_key(item)をitem in items:に置換Py3対策 #"
+ print u"# #"
+ print u"# 0.0.18 2009-08-26 SQLiteでDB検索機能追加開始 #"
+ print u"# #"
print u"# 0.0.17 2009-07-28b 記載をsjisからutf8に変更し、文字化け対策 #"
- print u"# タイトル長Shiftとカッコ文字対策の干渉調整#"
+ print u"# 番組名長Shiftとカッコ文字対策の干渉調整#"
print u"# 0.0.16 2009-07-28 規定値をdvd_label.confで設定可能に #"
print u"# toolフォルダのpathを返すtool_path()を汎用化#"
print u"# 0.0.15 2009-07-27 操作の?:簡易説明の追加 操作変更等 #"
@@ -62,11 +78,16 @@
def dsp_bug():
print u"\n############################# TODO & BUGS #############################"
print u"# 既知の課題 2009-07-25 #"
+ print u"# 0.0.21 「R」でデータ登録する仕様に変更。複数回実行すると2回書込む #"
+ print u"# 0.0.19 操作性(ユーザインターフェイス)が今一つすっきりしない #"
+ print u"# 0.0.19 日付と録画時間が正しく抽出出来ないことがある #"
+ print u"# 0.0.19 検索等の活用ではまだTITLESテーブルしか使っていない #"
+ print u"# 0.0.19 複数回処理するとDBに複数回書込むいい加減な仕様になっている #"
+ print u"# 0.0.18 SQLiteでDB検索機能追加開始 init_db():DBファイル有無で初期化 #"
print u"# 0.0.17 そろそろPython3との互換を考えて書かないとな #"
print u"# 0.0.17 詳細の操作方法説明が未完成だぞ #"
print u"# 0.0.17 DB検索もするなら、そろそろGUIに移行したいな #"
- print u"# 0.0.17 DB検索との連携が出来るといいな #"
- print u"# 0.0.17 UTF8記述としたが、中身はShift_JIS想定のコードのまま #"
+ print u"# 0.0.17 DB検索との連携が出来るといいな(0.0.18移行で対応) #"
print u"# 0.0.14 Internationalization #"
print u"# 0.0.14 DVD-VR以外のFormat分も作りたい。でもFormatが判らない #"
print u"# 0.0.14 全項目を取得出来る様にしたい(ex. Chapter) #"
@@ -77,47 +98,139 @@
def howto():
print u"\n############################# MINI HOW TO #############################"
print u"# #"
+ print u"# * 改行 : DVD-VIDEO IFO内の番組名情報を表示 #"
print u"# #"
- print u"# * 改行 : 現設定で繰返実行しDVD-VIDEOのIFO内のタイトル情報を表示 #"
+ print u"# * Q : このツールを終了 #"
print u"# #"
- print u"# * ±n : メインタイトル文字列長をbite数分増減します。 #"
- print u"# +2 : メインタイトル文字列長が2bite増え、 #"
- print u"# 個別のタイトルがその分短くなります。 #"
- print u"# -1 : メインタイトル文字列長が1bite減り、 #"
- print u"# 個別のタイトルがその分長くなります。 #"
+ print u"# * ±n : メイン番組名(ディスク名)文字列長をbite数分増減します。 #"
+ print u"# +2 : メイン番組名文字列長が2文字増え、 #"
+ print u"# 個別の番組名がその分短くなります。 #"
+ print u"# -1 : メイン番組名文字列長が1文字減り、 #"
+ print u"# 個別の番組名がその分長くなります。 #"
+ print u"# #"
+ print u"# * R : 簡単な検索処理を目的としたデータベースに登録します。 #"
+ print u"# #"
+ print u"# * S : 登録済の番組名の検索モードに移行します。 #"
print u"# #"
+ print u"# * T : 検索データをタブ区切りのテキストデータに変換して、 #"
+ print u"# 「DVD_Label_tab.TSV」の名でファイル出力します。 #"
+ print u"# #"
+ print u"# * D : ディスク名管理データを表示します。(暫定機能) #"
+ print u"# #"
+ print u"# * ? : この「MINI HOW TO」を表示します。 #"
print u"# * 〜: : ドライブ文字を指定して変更 ex. E: F: G: #"
print u"# or /〜 Linux系の場合は'/'で始まるpath指定 #"
print u"# (初期値はdvd_label.confで変更可能) #"
print u"# #"
- print u"# * Q : このツールを終了 #"
- print u"# #"
print u"# * DOC : READMEsjis.txtを表示 #"
print u"# #"
print u"# * BUG : このツールの抱える課題とBUGを表示 #"
print u"# #"
print u"# * HIST : このツールの開発履歴を表示 #"
+# print u"# #"
+# print u"# * HELP : HowTo.txtを表示(未対応) #"
+# print u"# #"
+# print u"# * F=〜 : 項目記号を指定し表示項目を変更(未対応) #"
+# print u"# 【項目記号】 #"
+# print u"# N : 連番 00〜99迄の数字 #"
+# print u"# T : 番組名 メイン番組名分をカットした番組名 #"
+# print u"# D : 日付 月/日の様式 ex. 1/ 1 〜 12/31 #"
+# print u"# H : 録画開始時 時:分:秒 ex. 0: 0: 0 〜 23:59:59 #"
+# print u"# M : 収録時間 時h分'秒" ex. 0' 1 〜 7h59'59" #"
+# print u"# ※ 現時点では、各項目は固定書式です。 #"
print u"# #"
- #print u"# * HELP : HowTo.txtを表示(未対応) #"
- #print u"# #"
- #print u"# * F=〜 : 項目記号を指定し表示項目を変更(未対応) #"
- #print u"# 【項目記号】 #"
- #print u"# N : 連番 00〜99迄の数字 #"
- #print u"# T : タイトル名 メインタイトルをカットしたタイトル名 #"
- #print u"# D : 日付 月/日の様式 ex. 1/ 1 〜 12/31 #"
- #print u"# H : 録画開始時 時:分:秒 ex. 0: 0: 0 〜 23:59:59 #"
- #print u"# M : 収録時間 時h分'秒" ex. 0' 1 〜 7h59'59" #"
- #print u"# ※ 現時点では、各項目は固定書式です。 #"
- #print u"# #"
- print u"# * ? : 操作の簡易説明(これ)を表示します。 #"
+ print u"#######################################################################"
+
+
+def howto_srch():
+ print u"\n########################## MINI HOW TO SEARCH #########################"
+ print u"# . : ピリオド1つだけを指定すると、検索モードから抜けます。 #"
+ print u"# 改行 : キーワードを指定せず改行すると全登録済データを表示します。 #"
+ print u"# ? : ?のみを指定することで、この検索モード操作説明を表示します。 #"
print u"# #"
+ print u"# キーワードの指定方法 #"
+ print u"# * 半角スペースを挟むことで複数のキーワード指定が可能です。 #"
+ print u"# * 複数キーワード指定の場合はその全てを含む番組名を表示します。 #"
+ print u"# * 現時点では番組名に対する検索のみに対応しています。 #"
print u"# #"
print u"#######################################################################"


#####################################################################
+#ネットからの拾いもの
+####################################################################################
+## unicode下のprint書式で全半角幅の区別がなく桁揃えが出来ない不具合に対処 ##
+#「RubyとPythonで全角文字を半角文字2文字として数える」(hush_puppy氏)より勝手に拝借 #
+# http://d.hatena.ne.jp/hush_puppy/20090226/1235661269 #
+# NICEですね。ソース公開されているhush_puppyさんに心より御礼申上げます。 #
+def ljust_kana(str, size, pad = " "): #関数0:指定幅の左寄せの #
+ space = size - width_kana(str) #関数1で定義 等幅文字列を返す #
+ if space > 0: #
+ str += pad * space #
+ return str #
+def width_kana(str): #関数1:半角換算の文字幅を返す #
+ all = len(str) # 全文字数 #
+ zenkaku = count_zen(str) # 全角文字数 #関数2で定義 #
+ hankaku = all - zenkaku # 半角文字数 #
+ return zenkaku * 2 + hankaku #
+def count_zen(str): #関数2:全角文字数をカウント #
+ from unicodedata import east_asian_width #
+ n = 0 #
+ for c in str: #
+ wide_chars = u"WFA" #
+ eaw = east_asian_width(c) #
+ if wide_chars.find(eaw) > -1: #
+ n += 1 #
+ return n #
+#  もうひとつの解としてはUTF8をShift_JISに変換後print書式を通し再度UTF8に変換する #
+# とこも考えられるがUTF8=>Shift_JISがうまくいかないんだな。それに頻繁なコード変換は#
+# 文字化け等の不具合発生の機会を増やすのでhush_puppyさんのアプローチが安全。ただ #
+# 出来るなら、print書式そのものを全角対応にしたいのが本音だ。 #
+## unicode下のprint書式で全半角幅の区別がなく桁揃えが出来ない不具合に対処 ##
+####################################################################################
+
+
+#####################################################################
#システム固有
-def dsp_titles(pa_dic={}): #元々、main()としていたものを改称。
+def init_db(db_file='DVD_Label.DB'):
+ """
+ db_file が存在しない場合に、DBとTABLEをCREATEする。
+ データのINSERT前なら、DBファイルを消して再実行で可。
+ データのINSERT後のTABLE変更は別途ALTER TABLEで実施。
+
+ """
+ from sqlite3 import connect
+ from os.path import exists,getsize
+ if exists(db_file): # db_file があり
+ if getsize(db_file)>0: # そのファイルが空でなかったら
+ return 0 # そのまま立去る
+ conn=connect(db_file) # DB作成と接続
+ cur=conn.cursor() # カーソル作成
+ sql=" CREATE TABLE if not exists DISKS(\n\
+ M_TITLE TEXT DEFAULT '' NOT NULL,\n\
+ D_DATE TEXT DEFAULT '' NOT NULL,\n\
+ TITLES INTEGER DEFAULT 0 NOT NULL,\n\
+ D_NO INTEGER DEFAULT 0 NOT NULL,\n\
+ PLACE TEXT DEFAULT '' NOT NULL,\n\
+ SHELF TEXT DEFAULT '' NOT NULL,\n\
+ BOX TEXT DEFAULT '' NOT NULL,\n\
+ D_DEL TEXT DEFAULT '' NOT NULL,\n\
+ PRIMARY KEY(M_TITLE,D_DATE,TITLES));"
+ cur.execute(sql) # SQL実行
+ sql=""" CREATE TABLE if not exists TITLES (
+ D_NO INTEGER DEFAULT 0 NOT NULL,
+ T_NO INTEGER DEFAULT 0 NOT NULL,
+ T_NAME TEXT DEFAULT '' NOT NULL,
+ T_DATE TEXT DEFAULT '' NOT NULL,
+ T_TIME TEXT DEFAULT '' NOT NULL,
+ D_DEL TEXT DEFAULT '' NOT NULL,\n\
+ PRIMARY KEY(D_NO,T_NO,T_NAME));"""
+ cur.execute(sql) # SQL実行
+ conn.commit() # 変更内容を保存
+ conn.close() # DBを閉じる

+
+
+def dsp_titles(pa_dic={},conf={},db_file='', regist=False): #表示と登録用関数
"""
ここで、他の関数を実行し結果をコンソール出力します
コマンドラインで引数を受付ける様に改造001
@@ -125,32 +238,28 @@
"""
from os.path import exists,join
from sys import argv
- from sys import stdout,stdin
- from codecs import getwriter,getreader
- stdout = getwriter('utf_8')(stdout)
- stdin = getreader('Shift_JIS')(stdin)
+ #from sys import stdout,stdin
+ #from codecs import getwriter,getreader
+ DISKs_DIC = {}
+ TITLEs = []
+ stdout_charset= conf["stdout_charset"]
+ stdin_charset= conf["stdin_charset"]
+ vr_charset= conf["vr_charset"]
+# stdout = getwriter(stdout_charset)(stdout)
+# stdin = getreader(stdin_charset)(stdin)

- hikisuu=argv #コマンドの引数を取得。ここでは+または-を伴なうShiftを取得
+ hikisuu=argv #コマンドの引数を取得。ここでは+または-を伴なうShiftを取得
shift=0
- if len(hikisuu)>=2:
- for h in hikisuu[1:]:
- if len(h)>=2 and len(h)<=3 and (h[0]=="+" or h[0]=="-") and h[1:]>='0' and h[1:]<="64":
- shift=int(h)
- break
if pa_dic.has_key("shift"): #操作入力のShift値が優先します。
shift=shift+pa_dic["shift"]

- ##DVD DRIVE文字を設定
- conf=conf_dic(tool_path(),"dvd_label.conf")
if conf.has_key("dvd_drive"): #DVDドライブ文字の規定値をdvd_label.confから取得
drive=conf["dvd_drive"]
- else:
- drive='E' #規定値はE
- if pa_dic.has_key("drive"): #操作入力のDVDドライブ文字をセット
+ if pa_dic.has_key("drive"): #操作入力のDVDドライブ文字をセット
drive=pa_dic["drive"]
if drive[1]==":":
drive="%s" % (drive[:1].upper())
- else: #コマンドラインの引数でDVDドライブ文字を指定可能にした。
+ else: #コマンドラインの引数でDVDドライブ文字を指定可能に
hikisuu=argv
if len(hikisuu)>=2:
for h in hikisuu:
@@ -163,28 +272,169 @@
if not exists("%s:\\DVD_RTAV\\VR_MANGR.IFO" % (drive)):
print u'%sドライブにはDVD-VIDEOの情報形式のディスクが入っていません。' % (drive)
return -1
- ymdhmss=ymdhms(drive) #A.Clipデータより録画日時リストを取得
- title_names=titles(drive) #B.Title名リストを取得
- main_ttl= de_kakko(main_title(title_names,pa_dic=pa_dic)) #C.メインTitle(番組名)の文字列を取得
+ ymdhmss=ymdhms(drive) #A.Clipデータより録画日時LISTを取得
+ title_names=titles(drive,vr_charset) #B.Title名リストを取得
+ main_ttl= de_kakko(main_title(title_names
+ ,pa_dic=pa_dic)) #C.メインTitle(番組名)の文字列を取得

- #print main_ttl
main_ttl_len=len(main_ttl)+shift
- #print ymdhmss[0]
- dt=u"'%0d.%d.%d %02d:%02d" % tuple(ymdhmss[0][0][0:5]) # リストをタプル化し必要な5要素を日付文字列化
- print
+ dt=u"'%0d.%d.%d %02d:%02d" % tuple(ymdhmss[0][0][0:5]) # リストをタプル化必要な
+ print # 5要素を日付文字列化
#print main_ttl.rstrip(),dt,u"〜"
- print title_names[0][:main_ttl_len],dt,u"〜\n"
+ DISKs_DIC['M_TITLE'] = title_names[0][:main_ttl_len]
+ DISKs_DIC['D_DATE'] = u"%4d-%02d-%02d %02d:%02d:%02d" % tuple(ymdhmss[0][0][0:6]) #11-02-12:月日2文字に
+ DISKs_DIC['TITLES'] = len(title_names)
+ sql="SELECT MAX(D_NO) FROM DISKS;" #最大Disk番号を取得するSQL文
+ n = db_query(sql=sql,db_file=db_file)[0][0] #そのを実行で最大DiskNo取得
+ if n is None: #無い時は、
+ n=0 # 0に
+ d_no = n+1 #新Disk番号を決め
+ DISKs_DIC['D_NO'] = d_no #それを代入
+ #M_TITLE = title_names[0][:main_ttl_len] #DB INSRT用
+ #D_DATE = dt #DB INSRT用
+ #TITLES = len(title_names) #DB INSRT用
+ #D_NO = db_query(sql=sql,db_file=db_file)[0][0]+1 #DB INSRT用
+ print title_names[0][:main_ttl_len],dt,u"〜"
+ print u"No. 番組名",
+ s=u" "
+ print s[width_kana(title_names[0][:main_ttl_len]):],
+ print u"月/日時h分\'秒\" DiskNo"
#print "\n%s %s〜\n" % (main_ttl,dt) #ここで、メインTitleを表示
#print u"\n%s %s-\n" % (main_ttl,dt) #ここで、メインTitleを表示
+ sql_exists = """SELECT D_NO FROM TITLES WHERE T_NO='%s' and T_NAME='%s'
+ and T_DATE='%s' and T_TIME='%s'"""
i=0
for t in title_names:
+ TITLEs_DIC = {}
+ TITLEs_DIC['D_NO'] = d_no
d="%2d/%2d" % tuple(ymdhmss[i][0][1:3])
if ymdhmss[i][1][0]>0:
- tm="%2dh%2d\'%02d\"" % (ymdhmss[i][1][0],ymdhmss[i][1][1],ymdhmss[i][1][2])
+ tm= "%1dh%02d\'%02d\"" % (ymdhmss[i][1][0],ymdhmss[i][1][1],ymdhmss[i][1][2])
+ tmd="%1dh%02d\'\'%02d\"" % (ymdhmss[i][1][0],ymdhmss[i][1][1],ymdhmss[i][1][2])
+ # sqliteのSQL文のデータに「'」を含めるときには「''」で表記
else:
- tm=" %2d\'%02d\"" % (ymdhmss[i][1][1],ymdhmss[i][1][2])
- print u"%02d. %s %s %s" % (i+1,t[main_ttl_len:],d,tm) # 個別のTitleを2桁連番と月日付で表示
+ tm=" %2d\'%02d\"" % (ymdhmss[i][1][1],ymdhmss[i][1][2])
+ tmd=" %2d\'\'%02d\"" % (ymdhmss[i][1][1],ymdhmss[i][1][2])
+ TITLEs_DIC['T_NO'] = i+1
+ TITLEs_DIC['T_NAME'] = t
+ TITLEs_DIC['T_DATE'] = u"%4d-%02d-%02d %02d:%02d:%02d" % tuple(ymdhmss[i][0][0:6])
+ TITLEs_DIC['T_TIME'] = tmd
+ dnos = db_query(sql_exists % (TITLEs_DIC['T_NO'], TITLEs_DIC['T_NAME']
+ , TITLEs_DIC['T_DATE'], TITLEs_DIC['T_TIME']), db_file=db_file)
+ if len(dnos)>0:
+ dno_s=[]
+ for n in dnos:
+ dno_s.append('%3d' % (n[0]))
+ existsDB = u' ◎' + ','.join(dno_s)
+ else:
+ existsDB = u''
+ print u"%02d. %s %s %s%s" % (i+1,t[main_ttl_len:],d,tm,existsDB) # 個別のTitleを2桁連番

+ TITLEs.append(TITLEs_DIC) # と月日付で表示
+ i=i+1
+ if regist: #登録指定「R」時
+ ##DB INSERT
+ db_insert( fields=DISKs_DIC,table='DISKS', db_file=db_file) #tableのprimaryキー
+ heres=db_inserts(fields=TITLEs, table='TITLES',db_file=db_file)
+ if len(heres)==len(TITLEs):
+ print u'(全番組名登録済)',
+ elif len(heres)>0:
+ print u'登録済: ',
+ for here in heres:
+ print u'%02d' % (here+1),
+ else:
+ print u'新規に登録しました',
+
+
+##sqliteのDBへの汎用データ挿入関数
+def db_insert(fields={},table='',db_file='',here=-1):
+ """
+ sqliteのDBへの汎用データ挿入関数
+ 利用前に列名:値の形式の辞書を作りfieldsに渡します
+ here は、キー違反により書込が出来なかった場所を返す様にする為の引数
+ 利用は任意だが、DB管理上は必須でしょう。これはdb_inserts()でも活用。
+ """
+ from sqlite3 import connect,IntegrityError
+ from types import IntType,StringType,FloatType,UnicodeType
+ keys=fields.keys()
+ vals=[]
+ for k in keys:
+ if type(fields[k]) is StringType or type(fields[k]) is UnicodeType:
+ vals.append("'%s'" % fields[k])
+ elif type(fields[k]) is IntType:
+ vals.append('%d' % fields[k])
+ elif type(fields[k]) is FloatType:
+ vals.append('%lf' % fields[k])
+ else:
+ vals.append("%s" % fields[k])
+ sql="INSERT INTO %s(%s) VALUES(%s);" % (table,','.join(keys),','.join(vals))
+ conn=connect(db_file)
+ cur=conn.cursor()
+ try:
+ cur.execute(sql)
+ conn.commit()
+ f=here
+ except IntegrityError, (errno): # strerror
+ #print "sqlite3.IntegrityError(%s): %s" % (errno, strerror)
+ #print u'登録済',
+ f=here
+ finally:
+ conn.close()
+ return f
+
+
+def db_inserts(fields=[],table='',db_file=''):
+ """
+ 複数の辞書形式データのリストを連続して1つずつデータ挿入する汎用関数
+ fsはキー違反が発生した位置を配列で返すもの、違反がない場合は[]を返す
+ """
+ fs=[]
+ i=0
+ for f in fields:
+ f=db_insert(fields=f,table=table,db_file=db_file,here=i) #sqliteのDBへの
+ if f >=0: #汎用Data挿入関数
+ fs.append(f)
i=i+1
+ return fs
+
+
+def db_query(sql,db_file):
+ """
+ sqlite3汎用クエリ関数、タプルでデータを返す
+ """
+ from sqlite3 import connect
+ conn=connect(db_file)
+ cur=conn.cursor()
+ conn.commit();
+ cur.execute(sql)
+ datas=cur.fetchall()
+ conn.close()
+ return datas
+
+
+def dsp_disks(db_file):
+ """
+ DISKsテーブル活用に当ってのただ表示するだけの暫定関数
+ """
+ sql="SELECT M_TITLE, TITLES, D_DATE, D_NO, PLACE, SHELF, BOX, D_DEL \n\
+ FROM DISKS\n\
+ ORDER BY M_TITLE, D_DATE, D_NO, D_NO;"
+ datas=db_query(sql,db_file)
+ l=u"+----+--------------------+"
+ l=l+u"----------------------------------------------------------------+---++++"
+ t=u"|通番| date |"
+ t=t+u" disk title | 数||||"
+ print l
+ print t
+ print l
+
+ for line in datas:
+ m_title=ljust_kana(line[0], 64, pad = " ")
+ titles='%3d' % (line[1])
+ d_date=ljust_kana(line[2], 20, pad = " ")
+ d_no='%4d' % (line[3])
+ print u'|%s|%s|%s|%s|%s|%s|%s|%s' % (d_no, d_date, m_title, titles, line[4]
+ , line[5], line[6], line[7])
+ print l


def ymdhms(drive): #A.Titleの録画日時リストを取得
@@ -215,7 +465,12 @@
1. DVD-RAMのIFOファイル: http://www28.atwiki.jp/jennychan/pages/19.html by jennychan さん
2. RD-X4のIFOファイル : http://www28.atwiki.jp/jennychan/pages/20.html by jennychan さん
3. タイトルとチャプタ : http://www28.atwiki.jp/jennychan/pages/18.html by jennychan さん
- jennychanさんのDVD-VR IFOファイル解析がなければ作成は困難でした。心より感謝申上げます。
+ ※ jennychanさんのDVD-VR IFOファイル解析がなければ作成は困難でした。心より感謝申上げます。
+ 4. DVDコピーとIFOファイルのヘッダ
+ http://www005.upp.so-net.ne.jp/neko-note/index.files/3rd/cd-dvd/dcd-ifo.html
+ Video ManaGer(VMG)IFOとVideo Title Set(VTS)IFOファイルのヘッダ
+ http://page.freett.com/bombaya/neta/ifo.html
+ 2009-08-03memo for nextstep
"""
ymdhms_list=[]
addr_crip_list=int('0100', 16) #0100を10進数整数化
@@ -226,22 +481,20 @@
addr_crip_list_no=fpi.read(4) #a. ヘッダブロックにあるClipブロック位置を読取る
koko=koko+4
nums=bites2int(addr_crip_list_no) #バイト表記の整数を10進数整数に
- #print u"Clipブロックデータ位置: %10ld" % (nums)
- crip_list_addr10_0=nums
+ crip_list_addr10_0=nums #Clipブロックデータ位置

fpi.read(nums-koko) #Clipブロックデータ位置迄を読み飛ばす
koko=nums
flag=fpi.read(4) #この4バイトの違いでデータ記載位置が変わる
- #print [flag]
- koko=koko+4
+ koko=koko+4 # どちらに記述されたものかを「:」「.」で表記
if flag=='\x00\x00\x01\x02': # 詳細: http://www28.atwiki.jp/jennychan/pages/20.html
- print u"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n" # どちらで記述されたものかを表記
+ print u"::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n"
crip_info_addr="0080"
elif flag=='\x00\x00\x01\x01': # 詳細: http://www28.atwiki.jp/jennychan/pages/19.html
- print u"........................................................................\n"
+ print u"......................................................................\n"
crip_info_addr="0044"
- else: # 今のところ2つ以外は存在しないとは思われる。
- print u"||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
+ else: # 今のところ2つ以外は存在しないとは思われる。
+ print u"||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
crip_info_addr="0044"
#「Clipリスト」内「Clip数」を取得
addr_crip_su=int(crip_info_addr, 16)#0100を10進数整数化
@@ -249,15 +502,13 @@
koko=koko+addr_crip_su-4
suu=fpi.read(2) #Clip数の読込
koko=koko+2
- crip_su=bites2int(suu)
- #print u"Clip数:",crip_su
+ crip_su=bites2int(suu) #print u"Clip数:",crip_su
addr10_crips=[]
no=1
while no<=crip_su:
addr_crip=fpi.read(4)
koko=koko+4
addr10_crip=bites2int(addr_crip) #Clipの相対アドレスを10進数化
- #print addr10_crip,hex(addr10_crip),hex(crip_list_addr10_0+addr10_crip)
addr10_crips.append(addr10_crip)
no=no+1
p=0
@@ -269,10 +520,8 @@
koko=koko+2
ymdhms5=fpi.read(5) #録画年月日5biteデータの読込み
koko=koko+5
- ymdhms10=bites2int(ymdhms5)
- #print hex(ymdhms10)
+ ymdhms10=bites2int(ymdhms5) #print hex(ymdhms10)
mdhms2=format(ymdhms10,"b") #5biteを2進数文字列化 Python2.6 or laterで対応の関数
- #print mdhms2
year = int(mdhms2[:11], 2) #年11桁 2047年で折返し?
month = int(mdhms2[11:11+4],2) #月 4桁
day = int(mdhms2[15:15+5],2) #日 5桁
@@ -297,7 +546,7 @@
return ymdhms_list ##Clipの[録画年月日,収録時間]のリストを返す


-def titles(drive): #B.Title名リストを取得
+def titles(drive,vr_charset): #B.Title名リストを取得
"""
VR_MANGR.IFOを読んでTitle名を取得
header info
@@ -312,13 +561,10 @@
fpi=open("%s:\\DVD_RTAV\\VR_MANGR.IFO" % (drive),"rb")
koko=koko+addr_title_list
fpi.read(addr_title_list) #Titleブロック位置データ記載位置迄を読み飛ばす
-# print addr_title_list
addr_title_list_no=fpi.read(4) #ヘッダブロックにあるTitleブロック位置を読取る
koko=koko+4
nums=bites2int(addr_title_list_no) #バイト表記の整数を10進数整数に
-# print u"Titleブロックデータ位置: %10ld" % (nums)
fpi.read(nums-koko) #Titleブロックデータ位置迄を読み飛ばす
- ttl=[]
suu=fpi.read(2) ##Title数を読取り
title_su=bites2int(suu) #Title数を10進数化 2009-07-22 10進整数関数に置換え
print u"Title数:",title_su
@@ -327,7 +573,6 @@
t_name=""
while no<=title_su: #Title名を読取り、リスト格納
t=fpi.read(142) #Titleデータを読込む
- #ttl.append(t) #Title情報全部をリストへ格納: ttlは現在未活用
tn=t[68:68+64] #Title名データ全幅を取得
#バイナリデータ独特のヌルバイトx00をスペース文字に置換え。
i=-1
@@ -337,17 +582,17 @@
while tn[i]==chr(0): #bugが潜在:尻尾からx00を探し無条件でスペース化
t_name="%-64s" % (tn[:i]) # x00で終わるマルチバイト文字では要らぬお節介
i=i-1 #の可能性あり。でも、今の規格ではないかな
- t_name= "%-64s" % (t_name.rstrip()) #Shift_JISのままで半角スペース埋めの文字列を作ってから
- title_names.append(unicode(t_name,'Shift_JIS')) #UTF8に変換したTitle名をリスト格納
+ t_name= "%-64s" % (t_name.rstrip()) #Shift_JISのままで半角スペース埋めの文字列を作ってから
+ title_names.append(unicode(t_name,vr_charset)) #UTF8に変換したTitle名をリスト格納
no=no+1
fpi.close()
return title_names #Title名リストを返す


-def de_kakko(title_name): #「『(≪〈の様な括弧の開くで終わる場合にはそれを除く
- if (len(title_name)>=2 and (title_name[-1:]==u"「" or title_name[-1:]==u"(" or title_name[-1:]==u"『"
- or title_name[-1:]==u"≪" or title_name[-1:]==u"〈" or title_name[-1:]==u"“" or title_name[-1:]==u"‘"
- or title_name[-1:]==u"【")):
+def de_kakko(title_name): #「『(≪〈の様な括弧の開くで終わる場合にはそれを除く
+ if (len(title_name)>=2 and (title_name[-1:]==u"「" or title_name[-1:]==u"("
+ or title_name[-1:]==u"『" or title_name[-1:]==u"≪" or title_name[-1:]==u"〈"
+ or title_name[-1:]==u"“" or title_name[-1:]==u"‘" or title_name[-1:]==u"【")):
return title_name[:-1]
else:
return title_name
@@ -360,51 +605,13 @@
Shift_JISコードの第一バイトの場合: http://ja.wikipedia.org/wiki/Shift_JIS
現在、Shift_JISであることが前提の決め打ち。
"""
- from sys import argv
- shift=0
- hikisuu=argv #コマンドの引数を取得
- if len(hikisuu)>=2:
- for h in hikisuu[1:]:
- if len(h)>=2 and len(h)<=3 and (h[0]=="+" or h[0]=="-") and h[1:]>='0' and h[1:]<="64":
- shift=int(h)
- break
- else:
- pass #引数がないのでシフトは既定通りしません。
- if pa_dic.has_key("shift"):
- shift=shift+pa_dic["shift"]
- shift=0
p=0
- #print title_names
pt=title_names[0].rstrip()
m_ttl="%s" % (pt)
- #print u"pt=\"%s\"" % (pt)
for s in pt:
- ##print "s",s
for ttl in title_names[1:]:
- ##print "ttl",ttl
- #if ((0x81 <= ord(ttl[p]) and ord(ttl[p])<= 0x9f)
- # or (0xE0 <= ord(ttl[p]) and ord(ttl[p])<= 0xFC)):
- # print u"sjis1",
- #if (((0x81 <= ord(ttl[p]) and ord(ttl[p])<= 0x9f)
- # or (0xE0 <= ord(ttl[p]) and ord(ttl[p])<= 0xFC))
- # and ((0x40 <= ord(ttl[p+1]) and ord(ttl[p+1])<= 0x7E)
- # or (0x80 <= ord(ttl[p+1]) and ord(ttl[p+1])<= 0xFC))):
- # print u"SJIS",
- #if ttl[p].isalpha():
- # print u"isalpha",
- #print u"*",p,hex(ord(ttl[p])),ttl[p:]
if not ttl[:p]==pt[:p]:#pバイト分を比較して一致しない様になったら
- #return pt[:p-1+shift] #shiftは表示側で適用
return pt[:p-1]
- #if (((0x81 <= ord(ttl[p]) and ord(ttl[p])<= 0x9f) #Shift_JISでないので、
- # or (0xE0 <= ord(ttl[p]) and ord(ttl[p])<= 0xFC)) #この処理は要らない。
- # and ((0x40 <= ord(ttl[p+1]) and ord(ttl[p+1])<= 0x7E) #でも文字コード間互換
- # or (0x80 <= ord(ttl[p+1]) and ord(ttl[p+1])<= 0xFC))): #での課題発生も背負う
- # # 第一バイトの時は一つ前迄をメインTitleとし、文字化け回避 #ことになる。
- # #print u"_",p,hex(ord(ttl[p])),ttl[p:],"sjis1",ttl[:p] #恐らくDVD-VR規格上ては
- # return ttl[:p-2+shift] #実害はないとは思う。
- #else: #2009-07-28 COMMENT化
- # return ttl[:p-1+shift] #次回リリース時に消去
p=p+1
return pt #2009-07-15 add All Error when titles are same name.

@@ -419,8 +626,7 @@
def bites2int(bites):
i=0
for bite in bites:
- i=i*256+ord(bite)
-# print hex(ord(bite)),int(hex(ord(bite)),16)
+ i=i*256+ord(bite) # print hex(ord(bite)),int(hex(ord(bite)),16)
return i

#### 実行toolフォルダのpathを返す #### 2009-07-28 作成
@@ -466,66 +672,146 @@
return conf


-def main_loop(): #元々、実行ブロックだったものをそのまま関数化
+def conf_dvd_label(file_path="",file_name="",missing_message=""):
+ """
+ dvd_labelで利用するdvd_label.conf内で指定可能なもので
+ 設定がないものに既定値を与えkeyerrorの発生を抑える
+ 新たなパラメータを設定したときには必ずここに既定値登録
+ その後に、confへ記入
+ """
+ from locale import getdefaultlocale
+ conf=conf_dic(file_path=file_path, file_name=file_name
+ , missing_message=missing_message)
+ if not "dvd_drive" in conf:
+ conf["dvd_drive"] = "E"
+ if not "vr_charset" in conf:
+ conf["vr_charset"] = getdefaultlocale()[1] #Charset既定値
+ if not "stdin_charset" in conf:
+ conf["stdin_charset"] = getdefaultlocale()[1] #Charset既定値
+ if not "stdout_charset" in conf:
+ conf["stdout_charset"] = "UTF8"
+ if not "format" in conf:
+ conf["format"] = '"N T D H"'
+ return conf
+
+
+def search_title(db_file='',conf=[],op=0):
+ """
+ ラベル作成によりDB登録した番組名をキーワード検索
+ """
+ from sys import stdout,stdin
+ from codecs import getwriter,getreader
+ import codecs
+ ans=""
+ stdout_charset =conf["stdout_charset"]
+ stdin_charset =conf["stdin_charset"]
+
+ stdout = getwriter(stdout_charset)(stdout) #不要っぽい
+ stdin = getreader(stdin_charset)(stdin) #不要っぽい
+ while not (ans.strip().upper() == "."): #ピリオド時のみ終了しmain_loopへ戻る
+ print u'検索[.:終了, 改行:全表示, ?:簡易説明](複数キーワード指定は半角スペース区切り):',
+ ans = unicode(raw_input(),stdin_charset) # 文字列表示でUnicodeEncodeError: 'ascii' codec
+ if ans.upper()=='?': # can't encode characters in position 0-1:
+ howto_srch() # ordinal not in range(128)
+ else:
+ ss=ans.split(' ')
+ likes=[]
+ for s in ss:
+ likes.append("T_NAME LIKE '%%%s%%'" % (s.strip()))
+ sql=u"SELECT D_NO,T_NO,T_NAME,T_DATE,T_TIME FROM TITLES WHERE %s" % (' AND '.join(likes))
+ datas=db_query(sql,db_file)
+ for d in datas:
+ print u"%5d %2d %s %s %8s" % (d[0],d[1],ljust_kana(d[2],64),d[3],d[4])
+ if op==1:
+ try: # *.TSV Tab-Separated Value MIME type: text/tab-separated-values
+ print db_file.split('.')[0]+'_tab.TSV', u"書出し",
+ fpo=codecs.open(db_file.split('.')[0]+'_tab.TSV','w',stdin_charset) #
+ #只のopen()は因縁点けて通さず:UnicodeEncodeError: 'ascii' codec
+ #can't encode characters in position 0-29:ordinal not in range(128)
+ for d in datas:
+ fpo.write(u"%5d\t%2d\t%s\t%s\t%8s\r\n" % (d[0],d[1]
+ ,ljust_kana(d[2],64),d[3],d[4]))
+ fpo.close()
+ print u"完了"
+ return
+ except IOError, (errno, msg):
+ print errno, msg
+ print u"TSVファイルの書出しに失敗しました。"
+ print u"以前作ったファイルが使用中ではありませんか?"
+ print u"Excel等で読込んでいるなら、それを終了してから"
+ print u"再実行して試て下さい。"

+
+def main_loop(db_file=''): #元々、実行ブロックだったものをそのまま関数化
+ """
+ メインメニューを表示し入力を待つ
+ """
from sys import stdout,stdin
from codecs import getwriter,getreader
- stdout = getwriter('utf_8')(stdout)
- stdin = getreader('Shift_JIS')(stdin)
- dsp_adv()
cur_path=tool_path()
- conf=conf_dic(cur_path,"dvd_label.conf")
+ conf=conf_dvd_label(cur_path,"dvd_label.conf")
+ stdout_charset =conf["stdout_charset"]
+ stdin_charset =conf["stdin_charset"]
+ stdout = getwriter(stdout_charset)(stdout) #不要っぽい
+ stdin = getreader(stdin_charset)(stdin) #不要っぽい
+ dsp_adv()
+ init_db(db_file=db_file)
ans=""
drv=""
pa_dic={}
- while not (ans.upper() == "Q" or ans.upper() == "QUIT"): #Qだけの時は終了 2009-07-27 Change E to Q.
+ while not (ans.strip().upper()=="Q" or ans.upper()=="QUIT"): #Qで終了 09-07-27 Change E to Q.
params=ans.split(" ") #操作入力をスペース区切りで項目を取得
for p in params:
if len(p)>=2 and ((p[0].isalpha() and p[1]==":")
- or (p[0]=="/" and p[1].isascii())): #DVDドライブ指定があったなら
+ or (p[0]=="/" and p[1].isascii())): #DVDドライブ指定があったなら
drv="%s" % (p)
pa_dic["drive"]=drv #ドライブ指定変更
- dsp_titles(pa_dic=pa_dic)
- if len(p)>=2 and len(p)<=3 and (p[0]=="+" or p[0]=="-") and p[1:]>='0' and p[1:]<="64":
- shift=int(p)
- pa_dic["shift"]=int(p) #メインTitleのbite長の増減を辞書オブジェクトに"shift"として
- dsp_titles(pa_dic=pa_dic) #登録後、それを渡して、システム本体を実行。
- if p.upper()=="HELP": #ヘルプを表示
- dsp_textfile(cur_path,"HELP_SJIS.txt","現在準備中です。リリースをお待ちください。Mire")
- if p.upper()=="DOC": #READMEを表示
+ dsp_titles(pa_dic=pa_dic,conf=conf,db_file=db_file) ####
+ if (len(p)>=2 and len(p)<=3 and (p[0]=="+" or p[0]=="-") #Main Titleの
+ and p[1:]>='0' and p[1:]<="64"): #文字数を増減
+ shift=int(p) #メインTitleの文字列長の増減を辞書に
+ pa_dic["shift"]=int(p) #"shift"として登録後それを渡してシステム
+ dsp_titles(pa_dic=pa_dic,conf=conf,db_file=db_file) #本体を実行 ####
+ if p.upper()=="HELP": #ヘルプを表示(コンテンツ未作成)
+ dsp_textfile(cur_path,"HELP_SJIS.txt"
+ ,"現在準備中です。リリースをお待ちください。Mire")
+ if p.upper()=="DOC": #READMEを表示 DOC
dsp_textfile(cur_path,"README_SJIS.txt")
- if p.upper()=="BUG": #BUG課題を表示
+ if p.upper()=="BUG": #BUG課題を表示 BUG
dsp_bug()
- if p.upper()=="HIST": #更新履歴を表示
+ if p.upper()=="HIST": #更新履歴を表示 HIST
dsp_history()
- if p=="?": #操作説明表示
+ if p=="?": #操作説明表示 ?
howto()
- if p=="": #改行だけのときは、システム本体をそのまま実行
- dsp_titles(pa_dic=pa_dic)
+ if p.upper()=="R": #データ登録へ R
+ dsp_titles(pa_dic=pa_dic,conf=conf,db_file=db_file,regist=True)
+ if p.upper()=="S": #検索操作へ S
+ search_title(db_file=db_file,conf=conf)
+ if p.upper()=="T": #書出操作へ T
+ search_title(db_file=db_file,conf=conf,op=1)
+ if p.upper()=="D": #DISKsテーブルデータの表示 D
+ dsp_disks(db_file=db_file)
+ if p=="": #改行だけのときはシステム本体をそのまま実行
+ dsp_titles(pa_dic=pa_dic,conf=conf,db_file=db_file) ####

print u"\n"
if not drv=="": #現在のドライブ指定を表示
dsp_drv="(%s)" % (drv)
else:
dsp_drv=""
-# print u"",
- if pa_dic.has_key("shift"): #メインTitle名長の増減を表示
+ if pa_dic.has_key("shift"): #メイン番組名長の増減を表示
if pa_dic["shift"]<0:
- shift_str=u"%d" % (pa_dic["shift"])
- #print pa_dic["shift"]
+ shift_str=u"%d" % (pa_dic["shift"]) #print pa_dic["shift"]
elif pa_dic["shift"]==0:
- shift_str=u"±n"
- #print u"±n"
+ shift_str=u"±n" #print u"±n"
else:
shift_str=u"+%d" % (pa_dic["shift"])
else:
shift_str=u"±n"
-# print shift_str,
- print u'操作[改行:実行, Q:終了, %s:タイトル長増減, ?:簡易説明]%s:' % (shift_str,dsp_drv),
- ans = raw_input() # 文字列表示でUnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
-
-
+ m=u'操作[改行:実行, Q:終了, %s:番組名長増減, R:登録, S:検索, T:書出, ?:How?]%s:';
+ print m % (shift_str, dsp_drv),
+ ans = raw_input() # 文字列表示でUnicodeEncodeError: 'ascii' codec can't
+ # encode characters in position 0-1: ordinal not in range(128)
#####################################################################
#実行ブロック
-try:
- main_loop()
-except:
- pass
+if __name__ == "__main__":
+ db_file='DVD_Label.DB'
+ main_loop(db_file=db_file)
続きを読む
posted by Mire at 22:09 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2011年07月31日

DVD_Label0.0.21 データ管理機能付 公開の件

 DVD_Labelにタイトル管理機能付加 SQLITE編で、データ管理機能の付加に着手しながら、mire自身の個人利用では問題ないものの配布後の対応に不安を覚え、延ばし延ばしになっていたものを本日公開させて頂く。
 mire自身の個人利用ではDVDの番組タイトル名読込時に書込む仕様とし、一々登録作業をしなくて済む様にしていたが、これではディスク名となる番組名の共通部分の文字数を変更したときにも重複して書き込んでしまうので、あたかも複数枚のDVDが存在するかの様なデータ管理となってしまうので一般向けではないと判断し、「R」つまりRegist(登録)の頭文字を指定した場合にのみデータベースに書込む仕様に泣く泣く変更した。

 また、nsanuki様、ご要望のExcel等別アプリへのデータ取込みを実現する為の仕組みとして「T」つまりTransefer Text の頭文字を指定した場合に、「TSV Tab-Separated Values MIME type: text/tab-separated利用」でも紹介しているタブ文字区切りのテキストファイルを書出す様にした。

 「改行」のみの場合に表示する番組名の末尾には、そのデータベースと照合した結果登録済なら、登録時にデータベース上で付与したディスク番号を表示する様にしているので、登録の要不要が簡単に判断出来るものと思う。

 尚、以上の仕様を除き、基本的なデータベース書込みと検索につしいては、当方で長い利用試験を済ませているので、障害を含む可能性は低いと思うので、コード変更直後ではあるが今回公開に踏み切らせて頂いた次第だ。手動による一般的なテストは済ませているので重大なBugを抱えていることはないと思うが、全ての場合について確認出来ているかと言うとそうではないので、もし、不具合や仕様としておかしい動作がある様であれば、ここにコメント頂ければとても有難い。

DVD_Label 0.0.21 build 2011-07-31_21.52JST + ソースコードBlog掲載の為のソース整形

DVD_Label 0.0.21 build 2011-07-31_18.59JST


 但し、今回のリリースはテストリリースの為、この頁での掲載のみとし、1〜2週間試用し
問題がないものを正式リリースするので、それ迄はDVD_Label.zipは以前のままである。続きを読む
posted by Mire at 20:13 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年11月13日

【VNC動画収録】vnc2flv 20091103は凄いと思う

 今久方ぶりに人様の作ったシステムを使ってちょいと、興奮している。

 以前「【PC遠隔操作】RealVNCのLAN内利用」で、GUIでのシステム管理で紹介したVNCを使った動画録画ツールがPythonで提供されていた。当方が知らなかっただけなのだろうが、VNCで別途RealVNC等のクライアントで繋ぐ必要はない。地味だがコンソールでコマンドを叩くだけ、終了はキー割込みで終わらせるだけの極めてシンプルなものだが、VNCサーバ側のGUI画面をフルピッチのきれいな画面のままキャプチャーした動画がFLV形式で収録出来る。勿論、動画なのでFLVと言えども容量の心配は必要だか、PC操作の説明動画作成や簡易の動画の部分切出し等にも使えそうだ。ライセンスはMIT License(著作権表示を求める程度のBSD系より緩い)なので安心して使えそうだ。

 DLは、PyPIにも登録されているので、そこからVNC辺りのキーワード検索で容易に、vnc2flv 20091103に行き着くので、そちらから取得すると間違いないだろう。そこから本家頁もあり、英語の説明がある。

 Installは、DLしたファイルを解凍後、そのディレクトリ内で、「python setup.py install」をするだけだ。ただ、インストール時にコンパイルが伴うので、Windowsの場合は、当Blogで以前紹介したMinGWを入れて、それで対処出来る。本家説明では、TightVNCのインストールをリスティングしているが別に必要ない様だ。無事インストールが終わると、python/Scripts内に操作ツールのスクリプトがコピーされているのでそれを利用して、録画、編集、音声追加等が出来る。
K:\DownloadFiles\VNC\vnc2flv-20091103\vnc2flv-20091103>dir
ドライブ K のボリューム ラベルは HD-CEU2 です
ボリューム シリアル番号は 98E9-299B です

K:\DownloadFiles\VNC\vnc2flv-20091103\vnc2flv-20091103 のディレクトリ
2009/11/13 03:57 <DIR> .
2009/11/13 03:57 <DIR> ..
2009/11/13 03:57 <DIR> docs
2009/11/13 03:57 <DIR> flvscreen
2009/11/03 10:46 1,011 Makefile
2009/11/03 10:57 680 PKG-INFO
2009/07/22 23:22 20 README.txt
2009/08/29 20:01 1,265 setup.py
2009/11/13 03:57 <DIR> tools
2009/11/13 03:57 <DIR> vnc2flv
4 個のファイル 2,976 バイト
6 個のディレクトリ 909,109,813,248 バイトの空き領域

K:\DownloadFiles\VNC\vnc2flv-20091103\vnc2flv-20091103>python setup.py install
running install
running build
running build_py
creating build
creating build\lib.win32-2.6
creating build\lib.win32-2.6\vnc2flv
copying vnc2flv\audio.py -> build\lib.win32-2.6\vnc2flv
copying vnc2flv\d3des.py -> build\lib.win32-2.6\vnc2flv
copying vnc2flv\flv.py -> build\lib.win32-2.6\vnc2flv
copying vnc2flv\rfb.py -> build\lib.win32-2.6\vnc2flv
copying vnc2flv\video.py -> build\lib.win32-2.6\vnc2flv
copying vnc2flv\__init__.py -> build\lib.win32-2.6\vnc2flv
running build_ext
building 'flvscreen' extension
creating build\temp.win32-2.6
creating build\temp.win32-2.6\Release
creating build\temp.win32-2.6\Release\flvscreen
D:\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python26\include -IC:\Python26\PC -c flvscreen/flvscreen.c -o build\temp.win32-2.6\Release\flvscreen\flvscreen.o
writing build\temp.win32-2.6\Release\flvscreen\flvscreen.def
D:\MinGW\bin\gcc.exe -mno-cygwin -shared -s build\temp.win32-2.6\Release\flvscreen\flvscreen.o build\temp.win32-2.6\Release\flvscreen\flvscreen.def -LC:\Python26\libs -LC:\Python26\PCbuild -lpython26 -lmsvcr90 -o build\lib.win32-2.6\flvscreen.pyd
running build_scripts
creating build\scripts-2.6
copying and adjusting tools\flvrec.py -> build\scripts-2.6
copying and adjusting tools\flvcat.py -> build\scripts-2.6
copying and adjusting tools\flvdump.py -> build\scripts-2.6
copying and adjusting tools\flvaddmp3.py -> build\scripts-2.6
copying tools\recordwin.sh -> build\scripts-2.6
running install_lib
copying build\lib.win32-2.6\flvscreen.pyd -> C:\Python26\Lib\site-packages
creating C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\audio.py -> C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\d3des.py -> C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\flv.py -> C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\rfb.py -> C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\video.py -> C:\Python26\Lib\site-packages\vnc2flv
copying build\lib.win32-2.6\vnc2flv\__init__.py -> C:\Python26\Lib\site-packages\vnc2flv
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\audio.py to audio.pyc
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\d3des.py to d3des.pyc
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\flv.py to flv.pyc
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\rfb.py to rfb.pyc
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\video.py to video.pyc
byte-compiling C:\Python26\Lib\site-packages\vnc2flv\__init__.py to __init__.pyc
running install_scripts
copying build\scripts-2.6\flvaddmp3.py -> C:\Python26\Scripts
copying build\scripts-2.6\flvcat.py -> C:\Python26\Scripts
copying build\scripts-2.6\flvdump.py -> C:\Python26\Scripts
copying build\scripts-2.6\flvrec.py -> C:\Python26\Scripts
copying build\scripts-2.6\recordwin.sh -> C:\Python26\Scripts
running install_egg_info
Writing C:\Python26\Lib\site-packages\vnc2flv-20091103-py2.6.egg-info

K:\DownloadFiles\VNC\vnc2flv-20091103\vnc2flv-20091103>


 取敢えず、当方では、ディスプレィのないWindows2000で動いているVNCサーバにつないで、録画をしてみたが、その手操作による録画方法は以下の通り。「-o」で出力ファイル名を指定しない場合には、日付によるユニークなファイル名で、実行したカレントディレクトリにファイめが生成されるので、実質必須なものはVNCサーバが起動しているIP端末のIPだけだ。終了は判らなかったのでCtrl+Cでキー割込みを掛けた。それで特に問題ない様だ。
C:\>python C:\Python26\Scripts\flvrec.py -o D:\test2.flv 192.168.30.225
start recording
Password for 192.168.30.225:5900:
尚、今回はオプションなしでinstall したが、作者がデモとして収録した動画にある様に、必要により、「--prefix=」で任意の場所にインストールすることも可能である。unix系の場合はpathの通る/usr/localは最適でしょう。
 閲覧は、右の様にRealPlayerで任意の倍率全画面再生または手元PCの画面解像度が許せば等倍も可能だ。vnc2flv_20091103.png

 尚、気になったことは、このツールでは、コマンドを叩いた段階で録画がスタートしており真っ黒な画面が録画され始める訳だが、実際の画面が録画出来るのはパスワードを入れてログインした後なので、やたら黒い画面が長く違和感があることだ。編集すれば良いことだが、そこが設計として惜しい。ログイン成功時の信号で録画開始ということは難しいのかな?続きを読む
posted by Mire at 05:59 | Comment(0) | TrackBack(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年08月27日

DVD_Labelにタイトル管理機能付加 SQLITE編

 DBをsqliteに変更したことで、困ったことは、isqlに相当するsqlitek
DB管理ツールを知らないし、構造すらろくに判って無かった。でも、調べて見るとSQL文は同然ながらISO準拠でDVD_Label程度のローカル用途で気にするレベルではない。気になったのはデータ型が貧弱というか柔軟なこと当たりに違和感を感じるが、今回の用途では全く影響はない。
 また、Pythonで使う限り、標準化されているからだろうが、FIREBIRDと接続実行操作に大差はない。文字列はUTF8のみと考えて利用する点が要注意といったところか。

 尾ヒレなしに簡単に書くと次の通り。
from sqlite3 import connect
conn=connect(db_file)
cur=conn.cursor()
sql='SELECT A,B,C FROM MY_TABLE WHERE A=1;'
cur.execute(sql)
datas=cur.fetchall()
conn.commit()
conn.close()


DB自体の作成はconn=connect(db_file)での接続時に、そのファイルがなければ勝手に作成される。isqlで 「CREATE DATABASE ...」とかいう作業は要らない。また、作成したてのDBファイルは空で0バイトの大きさである点が他のRDBMSと異なる特徴かも。


DBとTABLE作成

ということで、DVD_LbelでのDBとTABLEがない時の初期化用関数は次の通りで、実行位置は
main_loop()の頭でinit_db(db_file=db_file)とする。DB利用の前で、db_fileファイル名を取得し、ループする前であればどこでも良い。


def init_db(db_file='DVD_Label.DB'):
"""
db_file が存在しない場合に、DBとTABLEをCREATEする。
データのINSERT前なら、DBファイルを消して再実行で可。
データのINSERT後のTABLE変更は別途ALTER TABLEで実施。

"""
from sqlite3 import connect
from os.path import exists,getsize
if exists(db_file): # db_file があり
if getsize(db_file)>0: # そのファイルが空でなかったら
return 0 # そのまま立去る
conn=connect(db_file) # DB作成と接続
cur=conn.cursor() # カーソル作成
sql=" CREATE TABLE if not exists DISKS(\n\
M_TITLE TEXT DEFAULT '' NOT NULL,\n\
D_DATE TEXT DEFAULT '' NOT NULL,\n\
TITLES INTEGER DEFAULT 0 NOT NULL,\n\
D_NO INTEGER DEFAULT 0 NOT NULL,\n\
PLACE TEXT DEFAULT '' NOT NULL,\n\
SHELF TEXT DEFAULT '' NOT NULL,\n\
BOX TEXT DEFAULT '' NOT NULL,\n\
D_DEL TEXT DEFAULT '' NOT NULL,\n\
PRIMARY KEY(M_TITLE,D_DATE,TITLES));"
cur.execute(sql) # SQL実行
sql=""" CREATE TABLE if not exists TITLES (
D_NO INTEGER DEFAULT 0 NOT NULL,
T_NO INTEGER DEFAULT 0 NOT NULL,
T_NAME TEXT DEFAULT '' NOT NULL,
T_DATE TEXT DEFAULT '' NOT NULL,
T_TIME TEXT DEFAULT '' NOT NULL,
D_DEL TEXT DEFAULT '' NOT NULL,\n\
PRIMARY KEY(D_NO,T_NO,T_NAME));"""
cur.execute(sql) # SQL実行
conn.commit() # 変更内容を保存
conn.close() # DBを閉じる
蛇足ながら、Pythonの場合SQL文の様に何行にも亘って書く場合には「\」を行の末尾に置いて書く方法と、引用符「"」「'」を3つ続けたもので囲めば改行が間にあっても良い。また、これ以外にも、分けて小まめに変数値を組込んで行くときはsql=sql+'%s...'の様にして行く場合もある。

 尚、この関数では、db_fileの存在とそのファイルサイズを確認することで初期化が必要かどうかの判断をしている。途中でTABLE構造を変更した場合には別途バージョンアップ用の関数で対応して行く必要があるだろう。


データ書込み

 次に考えないとならないとこは、表示しているタイトル情報を書込む関数だ。ここで一番注意しなければならないのがPRIMARY KEY重複時の対処だが、これも普通通り例外発生するので、「try 〜 except IntegrityError:」で対処した。また、汎用のINSERT INTOとする為には、挿入する値の型のtypeをチェックし、SQLを作成する様にすることと、前準備として列名と値の対の引数として辞書を作り渡すとこが判り易いと思う。

##sqliteのDBへの汎用データ挿入関数
def db_insert(fields={},table='',db_file='',here=-1):
"""
sqliteのDBへの汎用データ挿入関数
利用前に列名:値の形式の辞書を作りfieldsに渡します
here は、キー違反により書込が出来なかった場所を返す様にする為の引数
利用は任意だが、DB管理上は必須でしょう。これはdb_inserts()でも活用。
"""
from sqlite3 import connect,IntegrityError
from types import IntType,StringType,FloatType,UnicodeType
keys=fields.keys()
vals=[]
for k in keys:
if type(fields[k]) is StringType or type(fields[k]) is UnicodeType:
vals.append("'%s'" % fields[k])
elif type(fields[k]) is IntType:
vals.append('%d' % fields[k])
elif type(fields[k]) is FloatType:
vals.append('%lf' % fields[k])
else:
vals.append("%s" % fields[k])
sql="INSERT INTO %s(%s) VALUES(%s);" % (table,','.join(keys),','.join(vals))
conn=connect(db_file)
cur=conn.cursor()
try:
cur.execute(sql)
conn.commit()
f=here
except IntegrityError, (errno): #登録済
f=here
conn.close()
return f



 このキー違反フリーのdb_insert()を使って、複数データを連続挿入する関数が次のものだ。これはTITLESテーブルへの挿入に活用する。

def db_inserts(fields=[],table='',db_file=''):
"""
複数の辞書形式データのリストを連続して1つずつデータ挿入する汎用関数
fsはキー違反が発生した位置を配列で返すもの、違反がない場合は[]を返す
"""
fs=[]
i=0
for f in fields:
f=db_insert(fields=f,table=table,db_file=db_file,here=i) ##sqliteのDBへの汎用データ挿入関数
if f >=0:
fs.append(f)
i=i+1
return fs



 これで、やっと登録データ相手にQUERYが投げれる。

def db_query(sql,db_file):
"""
sqlite3汎用クエリ関数、タプルでデータを返す
"""
from sqlite3 import connect
conn=connect(db_file)
cur=conn.cursor()
cur.execute(sql)
datas=cur.fetchall()
conn.close()
return datas



 この単機能のdb_query()が吐くタプルデータを利用して検索表示を試作したものが次の関数。
ここでは、文字コード変換が結構鬼門だ。ついでながら、最終行では、タブ区切のテキストファイル書出機能をop==1を条件に付けているが
こちらもコメントにある通りだ。

def search_title(db_file='',conf=[],op=0):
"""
ラベル作成によりDB登録した番組タイトルをキーワード検索
"""
from sys import stdout,stdin
from codecs import getwriter,getreader
import codecs
ans=""
stdout_charset =conf["stdout_charset"]
stdin_charset =conf["stdin_charset"]

stdout = getwriter(stdout_charset)(stdout) #
stdin = getreader(stdin_charset)(stdin) #
while not (ans.strip().upper() == "."): #ピリオドのみの時だけ終了し、main_loopへ戻る
print u'検索[.:終了, A:全表示, ?:簡易説明](複数キーワード指定は半角スペース区切り):',
ans = unicode(raw_input(),stdin_charset) # 文字列表示でUnicodeEncodeError: 'ascii'
ss=ans.split(' ') # codec can't encode characters
likes=[] # in position 0-1: ordinal not in range(128)
for s in ss:
likes.append("T_NAME LIKE '%%%s%%'" % (s.strip()))
sql=u"SELECT D_NO,T_NO,T_NAME,T_DATE,T_TIME FROM TITLES WHERE %s" % (' AND '.join(likes))
datas=db_query(sql,db_file)
for d in datas:
print u"%5d %2d %s %s %8s" % (d[0],d[1],ljust_kana(d[2],64),d[3],d[4])
if op==1: # *.TSV Tab-Separated Values
fpo=codecs.open(db_file.split('.')[0]+'_tab.TSV' #MIME type: text/tab-separated
,'w',stdin_charset) #-values 只のopen()で応対すると
for d in datas: #因縁点けて通してくれない
fpo.write(u"%5d\t%2d\t%s\t%s\t%8s\n" % (d[0] #UnicodeEncodeError: 'ascii' codec
,d[1],ljust_kana(d[2],64),d[3],d[4])) #can't encode characters in position
fpo.close() # 0-29: ordinal not in range(128)



 取敢えず操作性無視の段階だが、動いているので、sqliteで問題なさそうだ。あと気になるのはDBのバックアップ体制の構築当たりと、
保管場所情報の手打ち入力り仕組み作り辺りと検索に柔軟性を加えることか。いや、操作性も考えないとならないか。
posted by Mire at 05:34 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年08月13日

【DVDタイトル管理】願望編 〜 DVD_LabelにDisk管理機能を付加したい

 DVD-VIDEOも枚数が少ない内はDVDディスク面へのラベル印刷だけでも何とかなるが、必要な1本を探すのに時間がかかることが出て来たので、そろそろ、ディスク管理機能の付加を考えてみたい。

 単純に手前味噌でやるなら、データベースサーバにFIREBIRDを使って終わりなのだが、配布を考えるとどうしたものかとの思いもありなかなか考えが先に進まない。普通なら、いきなりコーディングからスタートするのだが、そういうことで、じっくりと設計から取組んで行こうと思う。(2011-08-17追記: 技術論に興味ない方は「DVD_Label0.0.24 リリース(管理機能付)」をご覧の上正式リリースパッケージを入手して下さい。)


データベース構造


検索で使うテーブル

DISKs テーブル
Disk連番 D_NO 長整数 Primary key
メインタイトル M_TITLE UTF8文字列 32*3
先頭タイトルの日時 D_DATE TIMESTAMP
タイトル数 TITLES 長整数
場所 PLACE UTF8文字列 32*3
書棚 SHELF UTF8文字列 32*3
収納ケース CASE UTF8文字列 32*3
削除 D_DEL CHAR(1) DEDAULT ' '

TITLEs テーブル
Disk連番 D_NO 長整数 Primary key
タイトル順 T_NO 長整数 Primary key
フルタイトル名 T_NAME UTF8文字列 32*3
収録日時 T_DATE TIMESTAMP
収録時間 T_TIME TIME

※ 後は、CREATE INDEX で M_TITLE, T_NAME, T_DATE, T_TIME 当たりの検索速度を上げておくことが必要。

FIREBIRDでのデータ挿入方法
 DISKs_TEMP,TITLEs_TEMPという Primary keyを外したテーブルにINSERT INTOし、トリガーで、DISKs,TITLEsテーブル上のデータの存否を確認しなければ挿入、登録して行くのがMire流だ。KEYの例外時の対応はこれが楽なんだな。

 他のRDBMSの場合、トリガーがないので、この辺はPython側で、TABLEをSELECT しながらINSERT または try: 〜 except: で個別データ毎に例外処理で処理することになる。SQLite当たりならそうなるかな。インストーラで導入部分の自動化が出来るなら、FIREBIRD系がDBファイルが壊れにくいのでやはり一番無難かな。先ずは慣れているFIREBIRDで作り配布方法を考えるとするかな。

インターフェイス


 Mire流なら迷わずブラウザを使うのだが、PythonでのGUIに挑戦するのも悪くないのかもしれない。ブラウザを活用する場合Apache利用が楽だけど、配布を考えるとPythonでWebサーバを構えるのも一興。今回はブラウザでの制作した上で、気が向いたらGUI版を作成してみようかと思う。

 結論として、当初方針は、最終の配布を考慮しながら、FIREBIRD+PythonでのWEBインターフェイス活用という形で挑戦することにする。また、これもMire流なんだが、何か引っかかったら低い方に流しててっとり早く上げることにする。まあ、3ヶ月程度では仕上げたいと今は思っている。これを読んだ方、期待しないで待っていて下さい。

 尚、今回のツール作成では、実際の成果物以前の課題に対する決定過程もここに掲載して行く。同様のツール作成に興味のある方は追って行くと、それなりに得るものがあるかも(反面教師以外ないかな^^;;)。続きを読む
posted by Mire at 22:30 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年08月01日

「DVD-VIDEO TITLES LABELER - DVD_Label」の使い方(導入編)

0. 初めに
 dvd_labelは、DVD-VIDEOのDVDラベルを自作する際に、DVD-VIDEOのIFOファイルから、タイトルや録画日時そして収録時間等を抽出利用したいとの想いから作成したものである。

 単に利用したい方には、そのままWindowsで実行出来るdvd_label.exeを同梱しているので、ストレスなく利用出来るものと思う。このdvd_label.exeは、PythonコードのプログラムをWindowsで直接実行可能にするPy2EXEで生成したもので、それを生成するDist_Package自体もツールに同梱しているのでその処理内容も確認頂けるので安心してご利用頂けるものと思う。

 他方、仕組み自体に興味のある方にとっても、実行コードからパッケージ化迄の全てを公開したオープンソースなので、中身を調べ、好みの仕様にカスタマイズして独自版をリリースすることも可能だ。その為、このツール自体は100%ピュアなpythonコードと一部batファイルで記述すると同時にコメントを可能な限り挿入している。有効に活用頂けたならは嬉しく思う。


1. 何が出来るの
 お手持ちのPCのDVDドライブにDVD-VR形式のDVD-VIDEOを差し、実行すると、Windowsのコマンドプロンプトの窓が開き、以下の様にDVD-VIDEOに収録しているタイトル等の情報をDVDラベルに利用し易いと思う書式で出力することが出来る。それを手持ちのDVDラベル作成ソフトにコピー&ペーストで配置して写真の様なDVDラベルを作成し印刷したいとき活用するツールである。


K:\DVD_LABEL\DVD_Label_20110816>dvd_label.exe

######################################################################
# System NAME: DVD-VIDEO TITLES LABELER Ver.0.0.25alpha 2011-08-18 #
# Copyright : 2009- Mire(まあいいやあ) in Japan #
# Contact : http://pythonlife.seesaa.net/article/124770100.html #
######################################################################
接続DB: K:\DVD_LABEL\DVD_Label_20110816\DVD_Label.DB
......................................................................

Title数: 7

ここが聞きたい!名医にQ '2011.7.2 20:00 〜
No. 番組名 月/日時h分'秒" DiskNo
01. 「あなたの疑問に答えます!痔(じ)の悩 7/ 2 54'42"
02. 「これで安心!めまい」 7/ 9 54'41"
03. 「あなたの疑問に答えます!めまい」 7/16 54'41"
04. 「アンコ―ル 糖尿病対策」 7/23 54'42"
05. 「アンコ―ル 中高年の食事術」 7/30 54'42"
06. 「アンコ―ル 歩くときの痛み」 8/ 6 54'42"
07. 「危険を見逃すな!不整脈」 8/13 54'42"



操作[改行:表示, Q:終了, ±n:番組名長増減, R:登録, S:検索, T:書出, ?:How?]:
(2011-08-18: Version up で表示が変更になったので、差替)

 このツールはCUIコンソール動作なので左図の様なコマンドプロンプトの窓で動作。コピーしたい箇所の角から対角をDRAGするだけで矩形選択が出来るので後は改行でクリップボードコピーが完了。簡単だ。
dvd_label_sample.png 手持ちのラベル作成ソフトにテキストをコピペして以下の様な個別タイトル内容付きのDVDラベルを作成出来る。ラベル作成ソフトはお好みのものを利用出来る。フリーもあるが、当方は安い「ラベルマイティ セレクト2」で作成している。バンドル品なのでサンプルは少なめだが、ラベル用紙追加可能で、ケースラベル作成等でも使えるので満足している。正規商品の「ラベルマイティ」はユーザー数が多いメジャー製品の様なので助かる。

※ 当然ながらDVDケースやカード作成にも有効。

2. インストール作業(例)
 基本的に、提供ファイルは只の中身をそのまま収めたZIP圧縮ファイルなのでお好きなフォルダに解凍し、必要によりショートカットをデスクトップ上かクイック起動メニューに作って頂ければよいだけだ。以下にVista(XP等でも可)での具体的手順を念の為付けておく。
  1. エクスプローラ上でインストールするフォルダを準備
     例えば、C:\TOOLs\DVD_Label等のフォルダを作成

  2. DVD_LABEL.html から最新版のDVD_Label.zipを取得し、インストールするフォルダに保存。

  3. エクスプローラ上の左側に表示されている「DVD_Label.zip」をクリックして、中身を表示。

  4. 表示された中身を、インストールするフォルダ(ここではC:\TOOLs\DVD_Label)コピーの要領でドラッグ&ドロップして解凍

  5. インストールフォルダをクリックし開き、「dvd_label.exe」ファイルを画面上にドラッグ&ドロップしてショートカット作成


Download Pageの「Newest Files」のリンクで最新版のDVD_Label.zipをDL取得
UNZIP_DVD_Label_zip.png
UNZIP_DVD_Label_zip_drag_and_drop.png
dvd_label_make_shortcut_icon.png
3. 初回起動時の(推奨)設定
 尚、コピー&ペーストをするには、最初に起動したときに、開く「コマンドプロンプト」同等の窓の初期設定を変更しておくと便利なので、続いて、その他も含めた推奨設定を以下に付記しておく。

  1. 起動して開いた窓の左上角のアイコンをクリックして、「既定値(D)」を選択。

  2. 簡易編集モードを(窓の選択)内のオプションタブにある「簡易編集モード(Q)」をチェック。好みにより右図の当方設定を参考にその他も設定。このdvd_labelでは、出力されたテキストを頻繁にコピーするので、「簡易編集モード」のチェックは操作面から必須に近い。後の手順説明では「簡易編集モード」となっていることを前提に記述させて頂くご了承願いたい。

  3. 好みにより、「フォント」タブで、MSゴシックとしフォントの「サイズ(S)」を変更。

  4. 「レイアウト」タブで窓の大きさ(ウィンドウのサイズの幅(I)と高さ(E))とスクロールバッファ(高さ(H)で最大9999迄)を設定し手持ちのPC画面に合ったサイズに変更。

  5. 「画面の色」タブで文字と背景色を嗜好に合わせ設定。


 全ての設定が終わったら「OK」ボタンをクリックして設定完了。

dvd_label_defaut_setup.png
dvd_label_defaut_setup_option.png
dvd_label_defaut_setup_font.png
dvd_label_defaut_setup_layout.png
dvd_label_defaut_setup_window_color.png

FAQ (comming soon)





 利用編はちょいと疲れたので、後日書かせて頂く。
posted by Mire at 20:47 | Comment(14) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月31日

あれ? dvd_labelのdownload頁見えてるのかな?

 今日、たまたま、blogの管理画面で閲覧された頁を見ていてdvd_labelのdownload頁へのアクセスはあるのだが、プログラム本体へのアクセス記録がない。ひょっとしてファイル更新でしくじってるかもと思いもその管理頁からdownload頁のURLをクリックすると、予想に反してそのdownload頁自体が見つからないとなる。良く見るとドメイン名が微妙に違っていて http://pythonlife.seesaa.net/ でなく、 http://pythonlife.up.seesaa.net/ でアップしたファイルは登録されている様である。何処ぞの投稿でURLをミスっているんだろうと思い探してみるけど見つからない。それで、お願いです。

 もし、linkが切れて見えない箇所があれば、コメントに苦情を入れて頂ければ有難く存じます。尚、このblogでは、特別、本名を名乗れとかemail必須とか審査後掲載とか、面倒なことは一切していないので、個人情報は一切載せる必要はありません。是非、お気軽に、ご一報下さりたく伏してお願い申上げます。 m(_"_)m続きを読む
タグ:DVD-VR dvd_lavel
posted by Mire at 20:09 | Comment(1) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月20日

「DVD-VIDEO TITLES LABELER」配布ツール付

 DVDラベル作成で使えるDVD-VIDEOの録画タイトル名を抽出するツール「DVD-VIDEO TITLES LABELER」に配布パッケージ作成を自動化するpythonコードを追加した。
 目的は当方が配布パッケージを作成するときのpy2exeによるexeファイル更新忘れを防止する為だが、これにより誰でもPythonコードを改変した後、手軽に配布パッケージを作成出来ることになった。

 実際に配布パッケージを作るときと改変したPythonコードを直接実行するときに、Python2.6とそれ用のPy2exeをインストールしておいて頂く必要がある。余り大きな言語でもないので当方の場合、2.4,2.5,2.6の3バージョンを入れ使い分けている。他のバージョンのPythonを入れている場合に気を付けるべきことは、環境変数のPATHでどのPythonが先に指定されているかということで、単にpython.exeのみを指定したときに実行するバージョンが変わる可能性がある程度で通常気にするものではない。大いに複数バージョンの共存をしてみて欲しい。
最新版: DVD-VIDEO TITLES LABELER (初版: DVD_Label_2009-07-20_01.59JST.zip)
(今回のパッケージより解凍時にはフォルダ付解凍をして下さい。素ではフォルダー作成しません。)
実行する作業は次の通り。
1. py2exeによるWindows上の実行ファイルの生成
2. 生成した実行に必要なファイルのみコピーし不要フォルダを削除
3. 配布用のZIPファイルを日付付名称で作成

c:\Python26にインストールされている場合には恐らく無修整でDist_Package.batを実行するだけで、その実行日時付の名称のZIPファイルが作業フォルダの親フォルダに生成される。
#!c:\\Python26\\python.exe
# -*- coding: Shift_JIS -*-
def main():
"""
 この関数は、DVD_Labelのパッケージ作成を自動化するものである。
実行する作業は次の通り。
1. py2exeによるWindows上の実行ファイルの生成
2. 生成した実行に必要なファイルのみコピーし不要フォルダを削除
3. 配布用のZIPファイルを日付付名称で作成
"""
import os,shutil,time
from zipfile import ZipFile,ZIP_DEFLATED
ppi=os.popen("c:\\Python26\\python.exe setup.py py2exe","r")
lines=ppi.readlines()
for l in lines:
print l,
ppi.close()
if os.path.exists("dvd_label.exe"): os.remove("dvd_label.exe")
if os.path.exists("python26.dll"): os.remove("python26.dll")
shutil.copy2("dist\\dvd_label.exe",".\\")
shutil.copy2("dist\\python26.dll",".\\")
shutil.rmtree("dist")
shutil.rmtree("build")
src_dir="..\\DVD_Label"
files=os.listdir(src_dir)
now=time.localtime(time.time())
z = ZipFile('..\\DVD_Label_%4d-%02d-%02d_%02d.%02dJST.zip' % now[:5], 'w',ZIP_DEFLATED)
for f in files:
z.write(f)
z.close()

main()


良かったら、試してみて下さい。続きを読む
posted by Mire at 02:56 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月18日

「DVD-VIDEO TITLES LABELER」新版リリース

 DVD-VIDEO のラベルタイトルを抽出するツール「DVD-VIDEO TITLES LABELER」の変更は以下の通り。だいぶこなれました。
Binary files DVD_Label_20090716/dvd_label.exe and DVD_Label_20090718b/dvd_label.exe differ
diff -duwB DVD_Label_20090716/dvd_label.py DVD_Label_20090718b/dvd_label.py
--- DVD_Label_20090716/dvd_label.py Thu Jul 16 02:20:14 2009
+++ DVD_Label_20090718b/dvd_label.py Sat Jul 18 14:12:32 2009
@@ -1,15 +1,23 @@
#!c:\\Python26\\/python.exe
# -*- coding: Shift_JIS -*-
# ※ Windows の場合1行目はdummyです。
-#---------------------------------------------------------------------
-# NAME : DVD-VIDEO TITLES LABELER dvd_label.py
-# Version : 0.0.2pre 単独動作書きなぐり 2009.7.14
-# Copyright : Mire(まあいいやあ) http://pythonlife.seesaa.net/
-# Licence : GPL のつもり(レベルが低いので無意味かも^^;;)
-# Requirement : Python2.6 or later 但し、Wondowsでの決打ちあり
-# HowToRun : type 'python dvd_label.py' on command prompt
-# or make batch file
-######################################################################
+
+def dsp_adv():
+ print "######################################################################"
+ print "# System NAME : DVD-VIDEO TITLES LABELER Ver.0.0.5 2009-07-18 "
+ print "# Copyright : 2009- Mire(まあいいやあ) http://pythonlife.seesaa.net/"
+ print "# Licence : GPLに基づく利用と再配布をお願いします。 "
+ #print "# Requirement : Python2.6 or later 但しWondows,Shift_JISでの決打ちあり"
+ #print "# HowToRun : Type 'python dvd_label.py' on windows command prompt. "
+ print "######################################################################"
+
+def dsp_history():
+ print "# 0.0.5 2009-07-18 カッコ開くでメインタイトルが終わっている場合に対処(最終文字のみを対処)"
+ print "# 0.0.4 2009-07-18 パッケージングを誤ったポカしたバージョンです。なかったことにします^^;;"
+ print "# 0.0.3 2009-07-17 共通のメインタイトル名決定時のShift_JIS第一バイト共通時の文字化け対処"
+ print "# 0.0.2 2009-07-16 cygwin.dvd-vr不要の単独動作化 Py2EXEよるdvd_label.exeも含むパッケージ提供も開始"
+ print "# 0.0.1 2009-07-07 第一引数 で DVDドライブ文字を指定可能に"
+ print "# 0.0.0 2009-06-23 初版、cygwin上で動作するdvd-vrの力を借りて作成"

def main():
"""
@@ -18,9 +26,6 @@
第一引数 : DVDドライブ文字を指定
"""
import string,sys,os
- print "DVD-VIDEO TITLES LABELER Ver.0.0.2 2009-07-16 "
- print "(C) 2009- Mire(まあいいやあ) http://pythonlife.seesaa.net/"
- print "GPL"
#コマンドラインの引数でDVDドライブ文字を指定可能にした。
drive='E' #規定値はEのまま
hikisuu=sys.argv
@@ -41,7 +46,7 @@
return -1
ymdhmss=ymdhms(drive) #A.クリップデータより録画日時リストを取得
title_names=titles(drive) #B.タイトル名リストを取得
- main_ttl= main_title(title_names) #C.メインタイトル(番組名)の文字列を取得
+ main_ttl= de_kakko(main_title(title_names)) #C.メインタイトル(番組名)の文字列を取得
#print main_ttl
main_ttl_len=len(main_ttl)
if main_ttl[-2:]=='「':
@@ -68,13 +73,8 @@
2. 「クリップリスト」内「クリップ情報」への相対位置 : x0082(4bite x クリップ数)
d. 「クリップ情報」内「録画日時情報」への相対位置 : x0002(5bite)
e. 「録画日時情報」は2進数表記で以下の桁数で解釈
- 年 11桁 2047年で折返し? 前2biteはリザーブの可能性あり
- 月 4桁
- 日 5桁
- 時 5桁
- 分 6桁
- 秒 6桁
-
+ 年: 11桁, 月: 4桁, 日: 5桁, 時: 5桁, 分: 6桁, 秒: 6桁
+ 2047年で折返し? 前2biteはリザーブの可能性あり
アドレスの追い方
現在の読み込みポインタ位置をkokoに入れ管理する
ブロック内の相対アドレスは、ブロックの開始基準位置を足して絶対アドレス化する
@@ -201,7 +201,7 @@
i=-1
while tn[i]==chr(0): #bugが潜在:尻尾からx00を探し無条件でスペース化
t_name="%-64s" % (tn[:i]) # x00で終わるマルチバイト文字では要らぬお節介
- i=i-1
+ i=i-1 #今の規格ではないかな
#print [t_name]
title_names.append(t_name) #タイトル名をリスト格納
no=no+1
@@ -209,27 +209,41 @@
return title_names #タイトル名リストを返す


+def de_kakko(title_name): #「『(≪〈の様な括弧の開くで終わる場合にはそれを除く
+ if (len(title_name)>=2 and (title_name[-2:]=="「" or title_name[-2:]=="(" or title_name[-2:]=="『"
+ or title_name[-2:]=="≪" or title_name[-2:]=="〈" or title_name[-2:]=="“" or title_name[-2:]=="‘" or title_name[-2:]=="【")):
+ return title_name[:-2]
+ else:
+ return title_name
+
def main_title(title_names): #C.メインタイトル(番組名)の文字列を取得
"""
タイトル名の頭から一致する部分を番組タイトル名として返す。
1バイトずつ比較し一致しないタイトルのバイト位置で番組タイトル名を確定し返す
+ Shift_JISコードの第一バイトの場合: http://ja.wikipedia.org/wiki/Shift_JIS
+ 現在、Shift_JISであることが前提の決め打ち。
"""
import string
p=0
#print title_names
pt=title_names[0].rstrip()
+ m_ttl="%s" % (pt)
#print "pt=\"%s\"" % (pt)
for s in pt:
for ttl in title_names:
- if not ttl[:p]==pt[:p]:
+ if not ttl[:p]==pt[:p]:#pバイト分を比較して一致しない様になったら
+ if ((0x81 <= ttl[p-1] and ttl[p-1]>= 0x9f) or (0xE0 <= ttl[p-1] and ttl[p-1]>= 0xFC)) and p>1:
+ # 第一バイトの時は一つ前迄をメインタイトルとし、文字化け回避
+ return ttl[:p-2]
+ else:
return ttl[:p-1]
p=p+1
return pt #2009-07-15 add All Error when titles are same name.

-
+dsp_adv()
ans=""
-while not ans.upper() == "Y":
+while not ans.upper() == "E":
main()
print
print
- ans = raw_input('Do you want to end this program?:(Y/N): ')
+ ans = raw_input('Do you want to end this program? (EXIT=E): ')
diff -duwB DVD_Label_20090716/setup.py DVD_Label_20090718b/setup.py
--- DVD_Label_20090716/setup.py Wed Jul 15 14:16:36 2009
+++ DVD_Label_20090718b/setup.py Sat Jul 18 03:33:18 2009
@@ -9,5 +9,5 @@
setup(
options = {"py2exe": py2exe_options},
console = [
- {"script" : "dvd_label.py", "icon_resources": [(1,"dvd_lael_sample_img_bakshomondai-thumbnail2.ico")]}],
+ {"script" : "dvd_label.py"}],
zipfile = None)
続きを読む
posted by Mire at 04:42 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月16日

「DVD-VIDEO TITLES LABELER」リリース

 先にdvd_label.pyとして試作公開したものを「DVD-VIDEO TITLES LABELER」との名称で正式リリースします。
 リリースに当たり、cygwinやdvd-vrの依存をなくし、100%pureなPYTHONで記述しました。cygwinでのdvd-vrの文字コード制御の不具合をdvd-vr側で対応すると残念なことに、WindowsのDOSプロンプトではエラーが発生してしまい使えなくなりました。そこで已む無く今回、単独動作する様にしました。

実行と出力は次の通り。尚、DVDドライブは次の様にアルファベット1文字を指定して実行出来る。リリースはPy2exeによるexe形式とdvd_label.pyの2種類で、共にWindows での Shift_JIS利用の決め打ちとなっている。また、exeの動作にはpython26.dllが最低でも必要となっている。

配布ZIPファイル: DVD-VIDEO TITLES LABELER

C:\>dvd_label.exe D
..

タイトル数: 13

爆笑問題のニッポンの教養 '2008.9.9 23:00〜

01. 「“ニッポン”を疑え〜日本思想史 子安 9/ 9
02. 「“学校の怪談”のヒ・ミ・ツ〜民俗学・ 9/16
03. ▽デザインで世界を改造せよ〜先端デザイ 9/23
04. 「愛の政治学入門〜政治学・姜尚中〜」 9/30
05. 「“あ〜疲れた”の正体〜ウイルス学・近 10/ 7
06. 「宇宙を駆けるX〜X線天文学・小山勝二 10/21
07. 「超能力お見せします〜稲見昌彦〜」 10/28
08. 「21世紀の錬金術師〜材料科学・細野秀 11/ 4
09. 「日本語って“ヤバい”〜日本語学・山口 11/11
10. 「“飛行少年”と呼ばれて〜航空力学・東 11/18
11. スペシャル 爆笑問題×早稲田大学「平成 11/25
12. ▽誰(た)がためのロボットか?〜ロボッ 12/ 2
13. 「謎の巨大イカを追え!〜海洋生物学・窪 12/ 9


Do you want to end this program?:(Y/N): y

C:\>


#!c:\\Python26\\/python.exe
# -*- coding: Shift_JIS -*-
# ※ Windows の場合1行目はdummyです。
#---------------------------------------------------------------------
# NAME : DVD-VIDEO TITLES LABELER dvd_label.py
# Version : 0.0.2pre 単独動作書きなぐり 2009.7.14
# Copyright : Mire(まあいいやあ) http://pythonlife.seesaa.net/
# Licence : GPL のつもり(レベルが低いので無意味かも^^;;)
# Requirement : Python2.6 or later 但し、Wondowsでの決打ちあり
# HowToRun : type 'python dvd_label.py' on command prompt
# or make batch file
######################################################################

def main():
"""
ここで、他の関数を実行し結果をコンソール出力します
コマンドラインで引数を受付ける様に改造001
第一引数 : DVDドライブ文字を指定
"""
import string,sys,os
print "DVD-VIDEO TITLES LABELER Ver.0.0.2 2009-07-16 "
print "(C) 2009- Mire(まあいいやあ) http://pythonlife.seesaa.net/"
print "GPL"
#コマンドラインの引数でDVDドライブ文字を指定可能にした。
drive='E' #規定値はEのまま
hikisuu=sys.argv
#print hikisuu
if len(hikisuu)==2:
d=string.upper(hikisuu[1])
if len(d)==1 and (("A"<=d and d<="Z")):
drive=d
else:
print "引数:'%s'はドライブ文字として不適格です。アルファベットで1文字指定します。" % (drive)
elif len(hikisuu)>2:
print "引数が多すぎます。指定出来るのはドライブ文字としてのアルファベット1文字1つのみです。"
else:
pass #引数がないのでドライブ文字は既定の"E"として実行

if not os.path.exists("%s:\\DVD_RTAV\\VR_MANGR.IFO" % (drive)):
print '%sドライブにはDVD-VIDEOの情報形式のディスクが入っていません。' % (drive)
return -1
ymdhmss=ymdhms(drive) #A.クリップデータより録画日時リストを取得
title_names=titles(drive) #B.タイトル名リストを取得
main_ttl= main_title(title_names) #C.メインタイトル(番組名)の文字列を取得
#print main_ttl
main_ttl_len=len(main_ttl)
if main_ttl[-2:]=='「':
main_ttl='%s' % (main_ttl[:-2])
#print ymdhmss[0]
dt="'%0d.%d.%d %02d:%02d" % tuple(ymdhmss[0][0:5])
print "\n%s %s〜\n" % (main_ttl,dt)
i=0
for t in title_names:
d="%2d/%2d" % tuple(ymdhmss[i][1:3])
print "%02d." % (i+1),t[main_ttl_len:],d
i=i+1


def ymdhms(drive): #A.タイトルの録画日時リストを取得
"""
直接、クリップ情報内にある録画日時情報を取得
a. ヘッダ領域にある「クリップリスト」ブロックの開始位置 : x0100(4bite)
b. 「クリップリスト」内の頭4biteの値が「0x00000101」のときには、
1. 「クリップリスト」内「クリップ数」相対x0044(2bite)
2. 「クリップリスト」内「クリップ情報」への相対位置 : x0046(4bite x クリップ数)
c. 「クリップリスト」内の頭4biteの値が「0x00000102」のときには、
1. 「クリップリスト」内「クリップ数」相対x0080(2bite)
2. 「クリップリスト」内「クリップ情報」への相対位置 : x0082(4bite x クリップ数)
d. 「クリップ情報」内「録画日時情報」への相対位置 : x0002(5bite)
e. 「録画日時情報」は2進数表記で以下の桁数で解釈
年 11桁 2047年で折返し? 前2biteはリザーブの可能性あり
月 4桁
日 5桁
時 5桁
分 6桁
秒 6桁

アドレスの追い方
現在の読み込みポインタ位置をkokoに入れ管理する
ブロック内の相対アドレスは、ブロックの開始基準位置を足して絶対アドレス化する
ブロック内の移動は絶対アドレス-koko分を読み飛ばして行なう。
※ これによりファイルの開閉は1度で全てのクリップの録画日時情報を取得する。
いずれは、タイトル取得側も統合することで、より軽いものにしたいものだ。
"""
ymdhms_list=[]
addr_crip_list=int('0100', 16) #0100を10進数整数化
koko=0
fpi=open("%s:\\DVD_RTAV\\VR_MANGR.IFO" % (drive),"rb")
fpi.read(addr_crip_list) #クリップブロック位置データ記載位置迄を読み飛ばす
koko=koko+addr_crip_list
addr_crip_list_no=fpi.read(4) #a. ヘッダブロックにあるクリップブロック位置を読取る
koko=koko+4
nums=0
for s in addr_crip_list_no: #バイト表記の整数を10進数整数に
#print hex(ord(s)),int(hex(ord(s)),16)
nums=nums*256+ord(s)
#print "クリップブロックデータ位置: %10ld" % (nums)
crip_list_addr10_0=nums

fpi.read(nums-koko) #クリップブロックデータ位置迄を読み飛ばす
koko=nums
flag=fpi.read(4)
#print [flag]
koko=koko+4
if flag=='\x00\x00\x01\x02':
print "..\n"
crip_info_addr="0080"
elif flag=='\x00\x00\x01\x01':
print ".\n"
crip_info_addr="0044"
else:
print "...\n"
crip_info_addr="0044"
#「クリップリスト」内「クリップ数」を取得
addr_crip_su=int(crip_info_addr, 16) #0100を10進数整数化
fpi.read(addr_crip_su-4) #クリップブロックデータ位置迄を読み飛ばす
koko=koko+addr_crip_su-4
suu=fpi.read(2)
koko=koko+2
crip_su=0
for su in suu: #クリップ数を10進数化
crip_su=crip_su*256+ord(su)
#print "クリップ数:",crip_su
addr10_crips=[]
no=1
while no<=crip_su:
addr_crip=fpi.read(4)
koko=koko+4
addr10_crip=0
for su in addr_crip: #クリップの相対アドレスを10進数化
addr10_crip=addr10_crip*256+ord(su)
#print addr10_crip,hex(addr10_crip),hex(crip_list_addr10_0+addr10_crip)
addr10_crips.append(addr10_crip)
no=no+1
p=0
for addr10_crip in addr10_crips:
#print "crip=",hex(crip_list_addr10_0+addr10_crip)," koko=",hex(koko) #読込位置チェック
fpi.read(crip_list_addr10_0+addr10_crip-koko) #読み飛ばし
koko=koko+crip_list_addr10_0+addr10_crip-koko
fpi.read(2) #読み飛ばし
koko=koko+2
ymdhms5=fpi.read(5)
koko=koko+5
ymdhms10=0
for su in ymdhms5:
ymdhms10=ymdhms10*256+ord(su)
#print hex(ymdhms10)
mdhms2=format(ymdhms10,"b") #5biteを2進数文字列化 Python2.6 or later
#print mdhms2
year = int(mdhms2[:11],2) #年11桁 2047年で折返し?
month = int(mdhms2[11:11+4],2) #月 4桁
day = int(mdhms2[15:15+5],2) #日 5桁
hour = int(mdhms2[20:20+5],2) #時 5桁
min = int(mdhms2[25:25+6],2) #分 6桁
sec = int(mdhms2[31:31+6],2) #秒 6桁
ymdhms_list.append([year,month,day,hour,min,sec,0,0,0])
fpi.close()
return ymdhms_list


def titles(drive): #B.タイトル名リストを取得
"""
VR_MANGR.IFOを読んでタイトル名を取得
header info
x0130: タイトルブロックの位置
4: タイトル数の表記幅
142: タイトルデータ長
詳細は: http://www28.atwiki.jp/jennychan/pages/19.html
"""
import string
addr_title_list=int('0130', 16) #0130を10進数整数化
title_names=[] #タイトル名を入れるリスト(器)を準備
koko=0
fpi=open("%s:\\DVD_RTAV\\VR_MANGR.IFO" % (drive),"rb")
koko=koko+addr_title_list
fpi.read(addr_title_list) #タイトルブロック位置データ記載位置迄を読み飛ばす
# print addr_title_list
addr_title_list_no=fpi.read(4) #ヘッダブロックにあるタイトルブロック位置を読取る
koko=koko+4
nums=0
for s in addr_title_list_no: #バイト表記の整数を10進数整数に
# print hex(ord(s)),int(hex(ord(s)),16)
nums=nums*256+ord(s)
# nums=nums*256+int(hex(ord(s)),16) #蛇足だが、こちらが判り易いかな?
# print "タイトルブロックデータ位置: %10ld" % (nums)
fpi.read(nums-koko) #タイトルブロックデータ位置迄を読み飛ばす
ttl=[]
suu=fpi.read(2)
title_su=0
for su in suu: #タイトル数を10進数化
title_su=title_su*256+ord(su)
print "タイトル数:",title_su
fpi.read(2) #クリップ数読み飛ばし
no=1
while no<=title_su: #タイトル名を読取り、リスト格納
t=fpi.read(142) #タイトルデータを読込む
#ttl.append(t) #タイトル情報全部をリストへ格納: ttlは現在未活用
tn=t[68:68+64]
#print tn
#バイナリデータ独特のヌルバイトx00をスペース文字に置換え。
i=-1
while tn[i]==chr(0): #bugが潜在:尻尾からx00を探し無条件でスペース化
t_name="%-64s" % (tn[:i]) # x00で終わるマルチバイト文字では要らぬお節介
i=i-1
#print [t_name]
title_names.append(t_name) #タイトル名をリスト格納
no=no+1
fpi.close()
return title_names #タイトル名リストを返す


def main_title(title_names): #C.メインタイトル(番組名)の文字列を取得
"""
タイトル名の頭から一致する部分を番組タイトル名として返す。
1バイトずつ比較し一致しないタイトルのバイト位置で番組タイトル名を確定し返す
"""
import string
p=0
#print title_names
pt=title_names[0].rstrip()
#print "pt=\"%s\"" % (pt)
for s in pt:
for ttl in title_names:
if not ttl[:p]==pt[:p]:
return ttl[:p-1]
p=p+1
return pt #2009-07-15 add All Error when titles are same name.


ans=""
while not ans.upper() == "Y":
main()
print
print
ans = raw_input('Do you want to end this program?:(Y/N): ')
続きを読む
posted by Mire at 02:49 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月14日

Cygwin下でのDVD-VRでタイトルを表示させる

 作者とのやり取りでも、Cygwin下でのDVD-VRでタイトル表示出来ないのは、結論として、dvd-vrが出力Charsetの取得に使っているnl_langinfo(CODESET)が、現安定版のCygwin下では、全く機能せずCygwin側のbugであることが判った。

 そこで、どうするかなのだが、DVD-VIDEOのタイトルや録画日時を出力するツールが他に見当たらない現状では、改造する以外には、Linuxで利用するしかない。まあ、Linux PCを日常的に利用出来るユーザなんて少ないし、やはり、Windows PCにCygwin程度をインストールすれば動くものが欲しいところだ。

@オリジナルのdvd-vrをliviconvなしでmakeしたものを介して、dvd_label.py を使う。
 これが一番スマートかな? Cygwinが1.7になったら状況も変わるので現時点でのLANG処理不具合にたいする継接ぎPATCHは無駄になる。

Advd_label.py は使いたくない。単独で利用というならdvd-vr.c 内の「nl_langinfo(CODESET)」とあるところの全てを「"SHIFT_JIS"」に置換えてmakeすればよい。この程度の改造ならdvd_label.pyからdvd-vrを読んでも使える。
diff -du dvd-vr-0.9.1_org dvd-vr-0.9.1_sjis
Only in dvd-vr-0.9.1_org: dvd-vr (2).c
diff -du dvd-vr-0.9.1_org/dvd-vr.c dvd-vr-0.9.1_sjis/dvd-vr.c
--- dvd-vr-0.9.1_org/dvd-vr.c Sat Jul 11 18:49:40 2009
+++ dvd-vr-0.9.1_sjis/dvd-vr.c Tue Jul 14 19:53:35 2009
@@ -334,9 +334,11 @@

static bool text_convert(const char *src, size_t srclen, char *dst, size_t dstlen)
{
+ char * to_code;
bool ret=false;
#ifdef HAVE_ICONV
- iconv_t cd = iconv_open (nl_langinfo(CODESET), disc_charset);
+ to_code = "SHIFT_JIS";
+ iconv_t cd = iconv_open (to_code, disc_charset);
if (cd != (iconv_t)-1) {
if (iconv (cd, (ICONV_CONST char**)&src, &srclen, &dst, &dstlen) != (size_t)-1) {
if (iconv (cd, NULL, NULL, &dst, &dstlen) != (size_t)-1) { /* terminate string */
@@ -344,7 +346,7 @@
}
} else {
fprintf(stderr, "Error converting from %s to %s\n",
- disc_charset, nl_langinfo(CODESET));
+ disc_charset, to_code);
}
iconv_close (cd);
} else {
Only in dvd-vr-0.9.1_sjis: dvd-vr.exe
Only in dvd-vr-0.9.1_sjis: dvd-vr.o
Binary files dvd-vr-0.9.1_org/liconv_test.exe and dvd-vr-0.9.1_sjis/liconv_test.exe differ
Common subdirectories: dvd-vr-0.9.1_org/man and dvd-vr-0.9.1_sjis/man


Bnl_langinfo(CODESET) の代わりにgetenv("LANG")を使い整合性を高める。
 気乗りしなかったが、C言語は多分10年は使っていなかったのでリハビリの目的で書いてみたものが次のものだ。お陰で、「;」や変数、ポインタ宣言を忘れて怒られまくり、C言語独特の短縮型となっている関数名を英語のフルスペル気味に母音を含めて書いてしまい、まあ、ドべの運動会状態でした。でも、やるべき内容はシステム屋さんであれば言語の壁を越えて伝わるかと思う。
 まあ、そうは言っても、ここをお尋ねの方には日本語伝わってもC言語は読めねぇと仰る方もいると思うので、少しだけ解説。
 環境変数のLANGは利用PC(またはユーザ)の利用する言語を定義するものであるが、特に日本語の場合は、命名に統一性がないし、利用コードが何か読取ることは出来るが、頭にja_JP.というものが付いていたり、微妙にその後の部分も標準的なCHARSET表記(Shift_JIS,EUC-JP,UTF8)とは異なる。それを洩れない様にする表現する必要があるのである。
 ただ、当方は根っからの生粋の日本人なので、日本語利用時の課題解決しかわからないので、先ずは、DVD-VIDEOにShift_JISかEUC-JPでタイトル記述されている場合のみに影響する様にした。また、Cygwinで日本語が使えないのは「nl_langinfo(CODESET)」が常に「US-ASCII」を返すのでそれも条件としている。後はヨーロッパ系言語の作者の方が詳しので考えてもらうことにする。韓国や中国語等のマルチバイト言語の方は同様にPATCHってもらえば何とかなるものと思うし将来はUTF8化で共に行けるので逃げることにした。この程度の配慮はしないとこれ迄日本人が受けた苦しみを他の言語環境の方に意趣返しする様なものなのでそうした。

diff -du dvd-vr-0.9.1_org/dvd-vr.c dvd-vr-0.9.1/dvd-vr.c
--- dvd-vr-0.9.1_org/dvd-vr.c Sat Jul 11 18:49:40 2009
+++ dvd-vr-0.9.1/dvd-vr.c Tue Jul 14 16:38:14 2009
@@ -334,9 +334,42 @@

static bool text_convert(const char *src, size_t srclen, char *dst, size_t dstlen)
{
+ char * lang;
+ char * to_code;
bool ret=false;
+/* fprintf(stdinfo,"src:\"%s\" in text_covret()\n",src);
+ fprintf(stdinfo,"dst:\"%s\" in text_covret()\n",dst);
+ fprintf(stdinfo,"size_t dstlen:\"%d\" in text_covret()\n",dstlen);*/
#ifdef HAVE_ICONV
- iconv_t cd = iconv_open (nl_langinfo(CODESET), disc_charset);
+ /*2009-07-14 mire's AD HOC PATCH for Cygwin1.5.x. START*/
+ to_code = nl_langinfo(CODESET);
+ if (strcmp(to_code,"US-ASCII")==0 && (strcmp(disc_charset,"SHIFT_JIS")==0 || strcmp(disc_charset,"EUC-JP")==0))
+ {/* Mire don't know effect for other languages. Japanese user's PC charcter se:t Windows=Shift_JIS,Linux=EUC-JP and UTF8.*/
+ lang = getenv("LANG");
+ /*fprintf(stdinfo,"LANG:%s\n",lang);
+ fprintf(stdinfo,"to_code:%s\n",to_code);
+ fprintf(stdinfo,"disc_charset:%s\n",disc_charset);*/
+ if (strcmp(lang,"ja_JP.Shift_JIS")==0 || strcmp(lang,"ja_JP.PCK")==0)
+ {
+ to_code = "SHIFT_JIS";
+ }
+ if (strcmp(lang,"ja_JP.EUC-JP")==0 || strcmp(lang,"ja_JP.eucJP")==0 || strcmp(lang,"ja_JP.EUC")==0 || strcmp(lang,"ja_JP.ujis")==0)
+ {
+ to_code = "EUC-JP";
+ }
+ if (strcmp(lang,"ja_JP.UTF8")==0)
+ {
+ to_code = "UTF8";
+ }
+ if (strcmp(lang,"C")==0)
+ {
+ strcpy(to_code,disc_charset);
+ }
+ /*fprintf(stdinfo,"to_code:%s\n",to_code);*/
+ }
+ /*2009-07-14 mire's AD HOC PATCH for Cygwin1.5.x. END*/
+
+ iconv_t cd = iconv_open (to_code, disc_charset); /*2009-07-14 mire's AD HOC PATCH for Cygwin1.5.x.*/
if (cd != (iconv_t)-1) {
if (iconv (cd, (ICONV_CONST char**)&src, &srclen, &dst, &dstlen) != (size_t)-1) {
if (iconv (cd, NULL, NULL, &dst, &dstlen) != (size_t)-1) { /* terminate string */
@@ -344,7 +377,7 @@
}
} else {
fprintf(stderr, "Error converting from %s to %s\n",
- disc_charset, nl_langinfo(CODESET));
+ disc_charset, to_code); /*2009-07-14 mire's AD HOC PATCH for Cygwin1.5.x.*/
}
iconv_close (cd);
} else {


 まあ、見るからに幼稚なPATCHなので、判り易いと思う。
CharsetがSHIFT_JISとなるのはLANGがja_JP.Shift_JIS,ja_JP.PCKとなっている場合のみ。EUC-JPとなるのはLANGがja_JP.EUC-JP,ja_JP.eucJP,ja_JP.EUC,ja_JP.ujisとなっているとき。UTF8となるのはja_JP.UTF8の一つのみだ。また、LANGがCのときには文字コード変換させてはならんいのでdisc_charsetを宛がうことにしているだけだ。
後は、nl_langinfo(CODESET)を何度も書くのは好きじゃないのでポインタto_codeをlang同様に宣言し格納し、開発時の確認用に変数の画面出力するfprintd\f(stdinfo,"〜:%s\n",〜)を入れ、終了後
「/* */」で囲んでコメント化している。とてもじゃないけど本家にPATCH採用される様な代物ではない、状況説明様である。

 取敢えず、当方のCygwin環境では正常にコード変換をする様であるので、海外の日本語アニメファンには利用価値があるのかもしれない。

 説明用のPATCHなのでファイル公開はしません、必要な方は、手でPATCHって下さい。まあ、メモ帳の枠内をコピペして、patchコマンドで充てれば変わりないけどね。


 で、私自身は、取敢えず、nl_langinfo(CODESET)を"SHIFT_JIS"に固定置き換えしたものをmakeして、次のCygwin1.7の正式リリースを待ち対応を考えたいと思います。
 ん〜、という内容を作者にレスしないとな。10年放置したC言語より気が重いだよな英語は。まだ当方の和製英語では伝わらないことがあるからね。^^;;

参考情報
環境変数マニュアル
ramble 999.08.17 (Tue)
http://www.bohyoh.com/CandCPP/C/index.html
BohYoh.com C言語講座続きを読む
posted by Mire at 17:35 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年07月11日

Getting Title of DVD-VIDEO by DVD-VR

 全くの好運と思うが、DVD-VRの作者からコメントを頂いた。英語なのだが中学英語程度レベルの自分でも、趣旨が理解出来たので、ここに先ずはコメントをした上で、作者のHomepageを訪ねそちらに同様のcommentを付けさせて頂いた。
 結論は、当方でTitleが取れなかった理由はlibiconvライブラリをCygwin環境で、インストールしていなからだよ。とのことでした。それで早速、Cygwinのsetup.exeを実行し見てみるとlibiconv2はあるが確かにlibiconvは選択していなかった。そこで選択しInstallして再度makeしてみた。

 結果は次の通り、一歩前進でもError。原因は不勉強なのでうかつなことは言えないが、素のCygwin では、glibc の 代わりに使われる newlib がまともでない為にエラーとなっている可能性が考えられる。http://www.kt.rim.or.jp/~kbk/zakkicho/08/zakkicho0805a.html


$ make clean

$ make
gcc -std=gnu99 -Wall -Wextra -Wpadded -DVERSION='"0.9.1"' -O3 -DNDEBUG -DHAVE_IC
ONV -DICONV_CONST="const" -c -o dvd-vr.o dvd-vr.c
gcc dvd-vr.o -liconv -Wl,-S -o dvd-vr.exe

$ make install
cp -p dvd-vr.exe /usr/local/bin
gzip -c man/dvd-vr.1 > /usr/local/share/man/man1/dvd-vr.1.gz

$ dvd-vr /cygdrive/e/DVD_RTAV/VR_MANGR.IFO
format: DVD-VR V1.1

VOB format 1...
tv_system : NTSC
resolution : 352x240
aspect_ratio: 16:9
video_format: MPEG2
audio_channs: 2
audio_coding: Dolby AC-3

VOB format 2...
tv_system : NTSC
resolution : 352x240
aspect_ratio: 16:9
video_format: MPEG2
audio_channs: 2 (mono)
audio_coding: Dolby AC-3

Number of programs: 14

num : 1
Error converting from SHIFT_JIS to US-ASCII
date : 2009-01-06 23:00:00
vob format: 1
size : 275159040

num : 2
Error converting from SHIFT_JIS to US-ASCII
date : 2009-01-13 23:00:00
vob format: 1
size : 277690368

num : 3
Error converting from SHIFT_JIS to US-ASCII
date : 2009-01-20 23:00:00
vob format: 1
size : 278837248

num : 4
Error converting from SHIFT_JIS to US-ASCII
date : 2009-01-27 23:00:00
vob format: 1
size : 278648832

num : 5
Error converting from SHIFT_JIS to US-ASCII
date : 2009-02-03 23:00:00
vob format: 1
size : 278069248

num : 6
Error converting from SHIFT_JIS to US-ASCII
date : 2009-02-10 23:00:00
vob format: 1
size : 278904832

num : 7
Error converting from SHIFT_JIS to US-ASCII
date : 2009-02-17 23:00:00
vob format: 1
size : 279406592

num : 8
Error converting from SHIFT_JIS to US-ASCII
date : 2009-02-24 23:00:00
vob format: 1
size : 278415360

num : 9
Error converting from SHIFT_JIS to US-ASCII
date : 2009-03-03 23:00:00
vob format: 1
size : 278724608

num : 10
Error converting from SHIFT_JIS to US-ASCII
date : 2009-03-10 23:00:00
vob format: 1
size : 275312640

num : 11
Error converting from SHIFT_JIS to US-ASCII
date : 2009-03-17 23:00:00
vob format: 1
size : 279955456

num : 12
Error converting from SHIFT_JIS to US-ASCII
date : 2009-03-24 22:20:00
vob format: 2
size : 769425408

num : 13
Error converting from SHIFT_JIS to US-ASCII
date : 2009-03-31 23:00:00
vob format: 1
size : 276267008

num : 14
Error converting from SHIFT_JIS to US-ASCII
date : 2009-04-07 23:00:00
vob format: 1
size : 276498432



 dvd-vr.c の112行には、#include とあるが、これが一般のLinuxと異なる部分で間違った日本語対応をしてしまうのだろう。

 根拠は薄弱なので濡れ衣かもしれないが、比較の為、駄目元でMinGWでのmakeもライブラリを色々と追加してやってみた結果でも、langinfo
で引っかかる。当方は確かに20年程前にはピュアなC言語で小さなプログラムを書いていたが、とてもここ辺り迄追って行く実力はないので取敢えず保留扱いとする。

 取敢えず、このことを英語にして、お礼を入れないといかんな。英語書く方が気が重いな。通じるかな? 誤解受けなきゃいいけどな。
タグ:DVD-VR mingw
posted by Mire at 21:17 | Comment(3) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年06月26日

パリーグ観戦(YAHOO動画)を大画面で

PacificStreaming.png パリーグでは全試合がYAHOO動画でインターネット配信されている。日頃はCATVで観戦しているのだが、西武主催試合は別途有料契約が必要となる為、これ迄はどうせよく切れるタイムラグが大きく臨場感か感じないとの想いがあり見ていなかった。
Lions_vs_Howks_2009-06-26_korose_kamiuchi.png でも実際につないでみると、先入観とはことなり、余り切れないし、そこそこの画質で、ストリーミング配信であるが故のタイムラグを気なしないなら、そんなに悪くないことが判った。ただ、画面が高画質と言ってもそこそこの大きさで物足りない。やはり見るからには1920x1200のディスプレイいっぱいに表示したくなるのが人情だろう。
 ところが窓を全画面表示にしようと思ったけど出来ない様に意地悪されているのだ。まあ、そんな場合は開く窓が普通のIEのものならば出来るはずなので、普通の窓を別に開き、URLをコピペして見みるとあっさりと騙されてくれた。そんなに性格は曲がっていない様だ。で、後は窓枠を掴んで、大きく拡げた上で、IEのステータスバー(窓の右下)にある倍率を200%にして、縦のスクロールバーで動画画面全部が表示される様にすれば完了である。

 尚、実際の動画再生には専用のアプリをインストールする必要がある。メッセージに従い素直に進めは終わる。


 話は変わるが、このブログ、Pythonをタイトルに掲げながら最近は全く関係のない話題が多いと思われていると思う。そんな方はアプリのフォルダーや開発サイトでソースコードを覗いてみて欲しい。この分はC:\Program Files\BBbroadcast\BBbroadcastCore\library.zip 当たりを覗くとハイ!!PythonライブラリをZIP化したものなんです。つまりPythonでてっとり早く開発しててっとり早くメンテしているってことなのです。他にも、セキュリティで取り上げたClamWinも同様で、あちらはグラフィック表示をwxPythonで、Windows環境での実行ファイル化にpy2exeを使っていることが、http://clamwin.svn.sourceforge.net/viewvc/clamwin/trunk/clamwin/Setup/ 辺りを見ると判る。まぁ、共に、"python23.dll"が添付配布されているので、今尚Python2.3のライブラリに依存しているってことなのだろう。興味のある方は深堀してみて下さい。

 実を言うと最近は動画系アプリを片っぱしから入れたくなる。今回も躊躇なく導入した。新しいデコーダーがタダで配布されていたらいいなと思う下心があるからである。今回その点は空振りでした。続きを読む
posted by Mire at 22:11 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年06月23日

DVD-VIDEO ラベルタイトル抽出 dvd_label.py

dvd_lael_sample_img_bakshomondai.png DVD-VIDEOには、録画した動画のタイトルが記録されている。でも、現実にはそのタイトルを手打ちや手仕事でDVD-VIDEOのラベルを作っているのが現実だ。  「そんな無駄な時間は、やはり使いたくない。」そう思い、時間をかけて作ってみた。お陰で楽になったが、果たして、システム作成使った時間分を取り戻すのに何か月かかるかなと思ったりしている。  さて、本論。今回作成した「DVD-VIDEO ラベルタイトル抽出 dvd_label.py」は実行すると以下の様に番組名と録画開始日時をディスクタイトルとして、各動画タイトルとその日付を連番付でリスティング してくれるものだ。後は必要な所を矩形選択して改行でクリップボードにコピーし、ラベル作成ソフト上で貼付けるだけである。当方にとっては文字列編集が全く不要となっている。
C:\>c:\Python25\python.exe dvd_label.py
タイトルブロックデータ位置:     191982
タイトル数: 14

爆笑問題のニッポンの教養 '09.1.6 23:00〜

001. ▽私が愛したゴリラ(前編)〜霊長類社会    1/ 6
002. ▽私が愛したゴリラ(後編)〜霊長類社会    1/13
003. 「万物は汚れている〜環境化学・田辺信介    1/20
004. 「建築のチカラ〜建築設計・西沢立衛〜」    1/27
005. 「おしゃべりな脳〜言語脳科学・酒井邦嘉    2/ 3
006. 「あなたの知らないメロディ―〜音文化学    2/10
007. 「芸術は“カラダ”だ〜美術解剖学・布施    2/17
008. 「ロボットの虫〜ロボット工学・三浦宏文    2/24
009. 「こころは水で作られる!?〜脳神経学・    3/ 3
010. 「学校は何も教えてくれない?〜教育社会    3/10
011.  成人の日スペシャル「“大人になる”と    3/17
012. スペシャル「ニッポン!チャチャチャ」      3/24
013. 「この世は“破れ”ている〜素粒子物理学    3/31
014. 「人口は口ほどにものを言う〜歴史人口学    4/ 7

C:\>
 まあねこの程度の小さなプログラムであり作るのも面倒だったので結構決め打ちと定数埋め込みで書いたが、ある程度中身が判る様にソースコードにはコメントを付けているので、詳しくはそちらを眺めてみて欲しい。

ソースコード付最新版(DL: DVD-VIDEO TITLES LABELER - DVD_LABEL)
#!c:/Python25/python.exe
# -*- coding: Shift_JIS -*-

#---------------------------------------------------------------------
#  NAME        : DVD-VIDEO ラベルタイトル抽出 dvd_label.py
#  Version     : 0.0.0pre つまり書きなぐりバージョン
#  Copyright   : Mire(まあいいやあ) http://pythonlife.seesaa.net/
#  Licence     : GPL のつもり(レベルが低いので無意味だが^^;;)
#  Requirement : OS: Windows,CYGWIN,dvd-vr,Python2.5 or later
######################################################################

def main():
    """
    ここで、他の関数を実行し結果をコンソール出力します
    """
    import string
    date_times=ymdhms()                 #A.タイトルの録画日時リストを取得
    title_names=titles()                #B.タイトル名リストを取得
    main_ttl= main_title(title_names)   #C.メインタイトル(番組名)の文字列を取得
    #print date_times[0]
    dt="'%0s.%s.%s %s" % (date_times[0][9:11],string.strip(date_times[0][12:14])
    ,string.strip(date_times[0][15:17]),date_times[0][-8:-3])
    print "\n%s %s〜\n" % (main_ttl,dt)
    main_ttl_len=len(main_ttl)
    i=0
    for t in title_names:
        d=date_times[i][12:17]
        print "%03d." % (i+1),t[main_ttl_len:],d
        i=i+1

def ymdhms():    #A.タイトルの録画日時リストを取得
    """
    dvd-vr を使って、タイトルの録画日時のリストを取得
    dvd-vrは、当方の環境ではCYGWIN上で実行する必要がある
    それを無理矢理でも、DOSプロンプトから実行する為には
    cygwin\\bin をカレントディレクトリにしてdvd-vr.exeを
    実行する必要がある。
    そこで、C: でカレントドライブをCにしてから
    続いて、cd cygwin\\binで、カレントに切替ている
    """
    import os,string
    ppi=os.popen("c:",'r')              #カレントドライブをCに
    ppi=os.popen("cd cygwin\\bin",'r')  #cygwin\\bin をカレントディレクトリに
    cmd="D:\\cygwin\\usr\\local\\bin\\dvd-vr.exe E:\\DVD_RTAV\\VR_MANGR.IFO"
    ppi=os.popen(cmd,'r')
    LINEs=ppi.readlines()               #標準出力を文字列リストに格納
    #print LINEs
    date_times=[]
    for l in LINEs:
        #num  : で始まるとタイトルの連番なので、それを整数取得
        if l[:7]=="num  : ":
            num=int(l[7:].strip())
            no=int(num)
        #date : で始まるとタイトルの録画日時情報、年月日と時分秒の文字列を取得
        if l[:7]=="date : ":
            ymd_hms=string.split(l[7:]," ")
            ymd=string.split(ymd_hms[0],"-")
            hms=string.split(ymd_hms[1],":")
        #sizeはタイトル情報の最後の項目の様なので、これが来たらリストへ出力
        if l[:7]=="size : ":
            #print num,ymd,hms
            y=int(ymd[0])
            m=int(ymd[1])
            d=int(ymd[2])
            h=int(hms[0])
            n=int(hms[1])
            s=int(hms[2])
            date_times.append('%05d: %4d/%2d/%2d %02d:%02d:%02d' % (no,y,m,d,h,n,s))
            #趣味の問題だが 00001: 2009/ 7/ 1 00:00:00 の形式で出力。
        #汎用化ならlocaltimeで返した方がよい。
        #print l,
    ppi.close()
    return date_times

def titles():    #B.タイトル名リストを取得
    """
    VR_MANGR.IFOを読んでタイトル名を取得
    header info
    x0130: タイトルブロックの位置
        4: タイトル数の表記幅
      142: タイトルデータ長
    詳細は: http://www28.atwiki.jp/jennychan/pages/19.html
    """
    import string
    addr_title_list=int('0130', 16)                           #0130を10進数整数化
    title_names=[]                  #タイトル名を入れるリスト(器)を準備
    koko=0
    fpi=open("E:\\DVD_RTAV\\VR_MANGR.IFO","rb")
    koko=koko+addr_title_list
    fpi.read(addr_title_list)       #タイトルブロック位置データ記載位置迄を読み飛ばす
#    print addr_title_list
    addr_title_list_no=fpi.read(4)  #ヘッダブロックにあるタイトルブロック位置を読取る
    koko=koko+4
    nums=0
    for s in addr_title_list_no:    #バイト表記の整数を10進数整数に
#        print hex(ord(s)),int(hex(ord(s)),16)
        nums=nums*256+ord(s)
#        nums=nums*256+int(hex(ord(s)),16) #蛇足だが、こちらが判り易いかな? 
    print "タイトルブロックデータ位置: %10ld" % (nums)
    fpi.read(nums-koko)                    #タイトルブロックデータ位置迄を読み飛ばす
    ttl=[]
    suu=fpi.read(2)
    title_su=0
    for su in suu:         #タイトル数を10進数化
        title_su=title_su*256+ord(su)
    print "タイトル数:",title_su
    fpi.read(2)            #クリップ数読み飛ばし
    no=1
    while no<=title_su:    #タイトル名を読取り、リスト格納
        t=fpi.read(142)    #タイトルデータを読込む
        ttl.append(t)      #タイトル情報全部をリストへ格納: ttlは現在未活用
        tn=t[68:68+64]
        #バイナリデータ独特のヌルバイトx00をスペース文字に置換え。
        i=-1
        while tn[i]==chr(0):   #bugが潜在:尻尾からx00を探し無条件でスペース化
            t_name="%-64s" % (tn[:i])  # x00で終わるマルチバイト文字では要らぬお節介
            i=i-1
        #print [t_name]
        title_names.append(t_name)     #タイトル名をリスト格納
        no=no+1
    fpi.close()
    return title_names          #タイトル名リストを返す

def main_title(title_names):    #C.メインタイトル(番組名)の文字列を取得
    """
    タイトル名の頭から一致する部分を番組タイトル名として返す。
    1バイトずつ比較し一致しないタイトルのバイト位置で番組タイトル名を確定し返す
    """
    p=0
#    print title_names
    pt=title_names[0]
    for s in pt:
        for ttl in title_names:
            if not ttl[:p]==pt[:p]:
                return ttl[:p-1]
        p=p+1


main()
OverView_of_VR_MANGR.IFO.png 蛇足ながら、解析時に使ったFoxbinの画面イメージを、参考迄添付しておく。上の反転位置(x0130)がタイトルブロックの開始アドレスであり、下の分がそのデータ部分を切り抜いたもの。下の反転部分はタイトル数のバイト表記部分である。5バイト目以降を142バイトずつ、タイトル数の回数分読み込み、その中からタイトル名を取り出している。ただ、固定長のバイナリの文字列データの終了位置はx00で埋められている為そのままでは使い辛いので半角スペースに置き換える必要がある。今回は取敢えずの対処なので、たまに文字化けが発生することになる。  尚、その後の変更は続きを読むで記事全体を表示してご覧頂きたい。 続きを読む
posted by Mire at 08:16 | Comment(0) | 動画環境 | このブログの読者になる | 更新情報をチェックする

2009年06月21日

DVD-VIDEO のタイトルと録画日時を取得

 当方では、Panasonic DMR-BW900 を使い、興味深い番組をDVD-Rに残すことがある。その際、DVD-Rのラベル作成で、そのタイトルと日付データを入れ、検索し易くしている。
 でも、DVD-VIDEOのタイトルと日付を目で見て再度入れていたのでは効率がとても悪い。ディスク内より情報取得出来ないかと思い色々とトライしてみた。どうも記録フォーマットは特許内容となっている様でNet検索が出来なかったので、正しい解析は出来ていないが取敢えずタイトルと録画日時別々ながらも取得可能に出来ることが判ったので、ここに記録しておく。

 先ずは、タイトルは、単純にMKEdotor等のテキストエディタで、「DVD_RTAV\VR_MANGR.IFO」を開くと、そのファイルの後ろの方にShift_JISで記述されていることが判る。データ長は142バイトなので、取敢えずであれば、エディタの折返しを142文字幅とし、最初のタイトル名で改行を加えた上で、矩形コピー(MKEditorの場合はCtrl+B)でタイトル名を一括でコピーして利用すればよい。

 録画日付については、解析出来なかったので、ひたすらググった結果、Pádraig Bradさんのdvd-vr と言うツールでコンソール出力出来ることが判った。Cソースコードなので読める方は解析して、それを生かすといいだろう。Cは暫くやっていないので当方は今回はパスするが、このツール自体はlinux, Mac OS X と Windowsではcygwin上でのみ動作する上、その前にmake installで、コンパイルし実行ファイルを作る必要がある。

 今回、当方では、WindowsにCYGWINを導入し対応した。CYGWIN導入については、別途改めて書くが、make installして出来るdvd-vr.exeファイルは、原則、CYGWINのコンソール上での利用となる。でも、実行時に必要となる「cygwin1.dll」の在るディレクトリに切替えて実行すると、普通のコマンドプロンプトでも実行出来る(やってないがPATHを通しても大丈夫なのかもしれない。)ので、Windows使いにも使えないことはないと思う。

 今回、残念なことにdvd-vr.exeでは、タイトル情報が全く取れなかった(メーカー差、規格バージョン差なのかもしれない)ので、もし当方が簡易で自動化する場合にはPythonでそれぞれ情報を実行させ情報を統合させ出力させることになると思う。時間゛か出来たら作るつもりだ。(6/23作りました:「DVD-VIDEO ラベルタイトル抽出 dvd_label.py」)

dvd-vr.exeの実行結果は以下の通り。尚、dvd-vr.exeとcygwin1.dllの位置はエクスプローラで検索し確認の上、それを叩いている。
D:\cygwin\bin>D:\cygwin\usr\local\bin\dvd-vr.exe E:\DVD_RTAV\VR_MANGR.IFO
format: DVD-VR V1.1

tv_system   : NTSC
resolution  : 352x240
aspect_ratio: 16:9
video_format: MPEG2
audio_channs: 2
audio_coding: Dolby AC-3

Number of programs: 10

num  : 1
date : 2008-12-23 22:00:00
size : 416256000

num  : 2
date : 2008-12-30 22:00:00
size : 654063616

num  : 3
date : 2009-01-06 22:00:00
size : 412358656

num  : 4
date : 2009-01-13 22:00:00
size : 413288448

num  : 5
date : 2009-01-20 22:00:00
size : 415524864

num  : 6
date : 2009-01-27 22:00:00
size : 414754816

num  : 7
date : 2009-02-03 22:00:00
size : 410560512

num  : 8
date : 2009-02-10 22:00:00
size : 411691008

num  : 9
date : 2009-02-17 22:00:00
size : 411080704

num  : 10
date : 2009-02-24 22:00:00
size : 412203008

Pádraig Bradさんのdvd-vr: http://www.pixelbeat.org/programs/dvd-vr/
Altair☆'s 三日坊主 blog: http://blog.livedoor.jp/altair8800/archives/64865915.html (この記述で見つけました。日本語PATCHを提供された方です。)続きを読む
タグ:DVD-VR
posted by Mire at 09:24 | Comment(3) | 動画環境 | このブログの読者になる | 更新情報をチェックする
月額見放題1,000円開始キャンペーンバナー(画像ありver)
紺碧の艦隊 ルパン三世 GREAT CHASE クリックプロモーション
<< 2013年01月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
カテゴリ
タグクラウド
ファン
利用中のオープンソース
最近のコメント
最近の記事
過去ログ
QRコード
レガシーなアプリはいかが?
Dell 法人のお客様ページ
  • 【法人様向け】デル、お得なキャンペーン情報
  • 法人のお客様向け ストレージソリューション
  • 法人のお客様向け ネットワークソリューション
  • 【SOHO法人様向け】デル・オンライン広告限定ページ
  • デル-個人のお客様ページ
  • 【個人のお客様向け】デル・オンライン広告限定ページ
  • オンライン広告限定キャンペーンページ
  • ソフトウェア&周辺機器 パソコン工房
    ツートップインターネットショップ(twotop.co.jp) マウスコンピューター/G-Tune
  • ×

    この広告は1年以上新しい記事の投稿がないブログに表示されております。