From 4e8b158c7102c42e0c38c086abeff15ff92ad0df Mon Sep 17 00:00:00 2001 From: yomguy Date: Thu, 30 Sep 2010 10:01:22 +0000 Subject: [PATCH] add win version git-svn-id: http://svn.parisson.org/svn/tools/trunk@120 457c0346-1240-4656-8a5a-9edca8063506 --- isp_tools/isp_trans.py | 12 +- isp_tools/isp_trans_win.py | 297 +++++++++++++++++++++++++++++++++++++ 2 files changed, 302 insertions(+), 7 deletions(-) create mode 100644 isp_tools/isp_trans_win.py diff --git a/isp_tools/isp_trans.py b/isp_tools/isp_trans.py index 5ddc6ef..91b293d 100644 --- a/isp_tools/isp_trans.py +++ b/isp_tools/isp_trans.py @@ -130,13 +130,12 @@ class ISPXLS: class ISPTrans(object): - def __init__(self, source_dir, dest_dir, log_file, water_img): + def __init__(self, source_dir, dest_dir, log_file): self.source_dir = source_dir self.dest_dir = dest_dir if not os.path.exists(self.dest_dir): os.makedirs(self.dest_dir) self.logger = Logger(log_file) - self.water_img = water_img self.uid = os.getuid() self.collection = ISPCollection(self.source_dir) @@ -240,9 +239,8 @@ Usage : python isp_trans.py /path/to/source_dir /path/to/transcoded_source_dir / """ % (version, author) else: - source_dir = sys.argv[-4] - dest_dir = sys.argv[-3] - log_file = sys.argv[-2] - water_img = sys.argv[-1] - i = ISPTrans(source_dir, dest_dir, log_file, water_img) + source_dir = sys.argv[-3] + dest_dir = sys.argv[-2] + log_file = sys.argv[-1] + i = ISPTrans(source_dir, dest_dir, log_file) i.process() diff --git a/isp_tools/isp_trans_win.py b/isp_tools/isp_trans_win.py new file mode 100644 index 0000000..f36e979 --- /dev/null +++ b/isp_tools/isp_trans_win.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/python +# +# Copyright (c) 2009-2010 Guillaume Pellerin + +# This file is part of YomGuy Tools. + +# TimeSide is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# TimeSide is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with TimeSide. If not, see . + +# Author: Guillaume Pellerin + +version = '0.2' +author = 'Guillaume Pellerin' + +import os +import re +import sys +import xlrd +import time +import logging + +from ctypes import * + +#PSAPI.DLL +psapi = windll.psapi +#Kernel32.DLL +kernel = windll.kernel32 + +def EnumProcesses(): + procs = [] + arr = c_ulong * 256 + lpidProcess= arr() + cb = sizeof(lpidProcess) + cbNeeded = c_ulong() + hModule = c_ulong() + count = c_ulong() + modname = c_buffer(30) + PROCESS_QUERY_INFORMATION = 0x0400 + PROCESS_VM_READ = 0x0010 + + #Call Enumprocesses to get hold of process id's + psapi.EnumProcesses(byref(lpidProcess), + cb, + byref(cbNeeded)) + + #Number of processes returned + nReturned = cbNeeded.value/sizeof(c_ulong()) + + pidProcess = [i for i in lpidProcess][:nReturned] + + for pid in pidProcess: + + #Get handle to the process based on PID + hProcess = kernel.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + False, pid) + if hProcess: + psapi.EnumProcessModules(hProcess, byref(hModule), sizeof(hModule), byref(count)) + psapi.GetModuleBaseNameA(hProcess, hModule.value, modname, sizeof(modname)) + procs.append("".join([ i for i in modname if i != '\x00'])) + + #-- Clean up + for i in range(modname._length_): + modname[i]='\x00' + + kernel.CloseHandle(hProcess) + + #print procs + ffmpeg_procs = 0 + for proc in procs: + if proc == 'ffmpeg.exe': + ffmpeg_procs += 1 + return ffmpeg_procs + +def get_pid(proc,uid): + """Get a process pid filtered by arguments and uid""" + (list1, list2) = os.popen4('pgrep -fl -U '+str(uid)+' '+'"'+proc+'"') + procs = list2.readlines() + pids = [] + if procs != '': + for proc in procs: + pid = proc.split(' ')[0] + command = ' '.join(proc.split(' ')[1:])[:-1] + pids.append(pid) + return pids + + +class Logger: + + def __init__(self, file): + self.logger = logging.getLogger('myapp') + self.hdlr = logging.FileHandler(file) + self.formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') + self.hdlr.setFormatter(self.formatter) + self.logger.addHandler(self.hdlr) + self.logger.setLevel(logging.INFO) + + def write_info(self, prefix, message): + self.logger.info(' ' + prefix + ' : ' + message.decode('utf8')) + + def write_error(self, prefix, message): + self.logger.error(prefix + ' : ' + message.decode('utf8')) + + +class ISPCollection: + + def __init__(self, dir): + self.dir = dir + self.dir_name = self.dir.split(os.sep)[-1] + self.file_list = os.listdir(self.dir) + + def xls_list(self): + file_list = [] + for file in self.file_list: + ext = os.path.splitext(file)[1] + if (ext == '.xls' or ext == '.XLS') and not file == '.' and not file == '..': + file_list.append(file) + return file_list + + def media_list(self): + list = [] + for file in self.file_list: + ext = os.path.splitext(file)[1] + if (ext == '.mpg' or ext == '.MPG' or ext == '.avi' or ext == '.AVI') and not file == '.' and not file == '..': + list.append(file) + return list + + +class ISPXLS: + + def __init__(self, file): + self.first_row = 1 + self.book = xlrd.open_workbook(file) + self.sheet = self.book.sheet_by_index(0) + self.cam_dirs = self.get_col(0) + self.sources = self.get_col(1) + self.courses = self.get_col(2) + self.dest_names = self.get_col(3) + self.starts_mn = self.get_col(4) + self.starts_s = self.get_col(5) + self.ends_mn = self.get_col(6) + self.ends_s = self.get_col(7) + self.forces = self.get_col(8) + self.size = len(self.sources) + + def get_col(self, col): + col = self.sheet.col(col) + list = [] + for cell in col[self.first_row:]: + #if cell.ctype == 1: + list.append(str(cell.value)) + return list + + def trans_dict(self): + data = {} + i = 0 + for source in self.sources: + data[str(i)] = {} + data[str(i)]['cam_dir'] = self.cam_dirs[i] + data[str(i)]['source_file'] = self.sources[i] + data[str(i)]['course'] = self.courses[i] + data[str(i)]['dest_name'] = self.dest_names[i] + data[str(i)]['start_mn'] = self.starts_mn[i] + data[str(i)]['start_s'] = self.starts_s[i] + data[str(i)]['end_mn'] = self.ends_mn[i] + data[str(i)]['end_s'] = self.ends_s[i] + data[str(i)]['force'] = self.forces[i] + i += 1 + return data + + +class ISPTrans(object): + + def __init__(self, source_dir, dest_dir, log_file): + self.source_dir = source_dir + self.dest_dir = dest_dir + if not os.path.exists(self.dest_dir): + os.makedirs(self.dest_dir) + self.logger = Logger(log_file) + self.uid = os.getuid() + + self.collection = ISPCollection(self.source_dir) + #self.sources = self.collection.media_list() + self.xls_file = self.collection.xls_list() + self.xls = ISPXLS(self.source_dir + os.sep + self.xls_file[0]) + self.trans_dict = self.xls.trans_dict() + #print self.trans_dict + + self.format = 'flv' + self.size = '480x270' + self.vb = '336k' + self.ab = '64k' + self.ar = '44100' + self.async = '500' + + self.server = 'parisson.com' + self.user = 'videojur' + self.server_dir = '/home/%s/videos/' % self.user + + mess = 'version %s started with the folowing parameters :' % version + self.logger.write_info('isp_trans', mess) + mess = 'format : %s , size : %s , vb : %s , ab : %s , ar : %s , async : %s' % \ + (self.format, self.size, self.vb, self.ab, self.ar, self.async) + self.logger.write_info('ffmpeg', mess) + + def rsync_out(self): + command = 'rsync -av --update %s/ %s@%s:%s/ & ' % (self.dest_dir, self.user, self.server, self.server_dir) + os.system(command) + + def transcode_command(self, source_file, start_time, duration, dest_file): + + # logo inlay + #command = 'ffmpeg -ss %s -t %s -i %s -vhook "/usr/lib/vhook/imlib2.so -x 517 -y 516 -i %s" -f %s -s %s -vb %s -acodec libmp3lame -ab %s -ar %s -async %s -y %s' % (start_time, duration, source_file, self.water_img, self.format, self.size, self.vb, self.ab, self.ar, self.async, dest_file) + + ## logo watermark + #command = 'ffmpeg -ss %s -t %s -i %s -vhook "/usr/lib/vhook/watermark.so -f %s" -f %s -s %s -vb %s -acodec libmp3lame -ab %s -ar %s -async %s -y %s &' % (start_time, duration, source_file, self.water_img, self.format, self.size, self.vb, self.ab, self.ar, self.async, dest_file) + + # normal + if duration == '-1': + command = 'ffmpeg -ss %s -i %s -f %s -s %s -vb %s -acodec libmp3lame -ac 1 -ab %s -ar %s -async %s -y %s & ' % (start_time, source_file, self.format, self.size, self.vb, self.ab, self.ar, self.async, dest_file) + else: + command = 'ffmpeg -ss %s -t %s -i %s -f %s -s %s -vb %s -acodec libmp3lame -ac 1 -ab %s -ar %s -async %s -y %s & ' % (start_time, duration, source_file, self.format, self.size, self.vb, self.ab, self.ar, self.async, dest_file) + return command + + def process(self): + counter = 0 + for source in self.trans_dict.iteritems(): + source_dict = source[1] + cam_dir = source_dict['cam_dir'] + source_file = source_dict['source_file'] + media = self.source_dir + os.sep + cam_dir + os.sep + source_file + course = source_dict['course'] + name = str(source_dict['dest_name']) + dest_dir = self.dest_dir + os.sep + 'videos' + course + if not os.path.exists(dest_dir): + os.makedirs(dest_dir) + dest = dest_dir + os.sep + name + '.' + self.format + + #print '

%s

' % (course, name, part) + + start_mn = int(float(source_dict['start_mn'])) + start_s = int(float(source_dict['start_s'])) + end_mn = int(float(source_dict['end_mn'])) + end_s = int(float(source_dict['end_s'])) + start = int(60 * start_mn + start_s) + if end_mn == -1 or end_s == -1: + duration = -1 + else: + end = 60 * end_mn + end_s + duration = int(end - start) + force_mode = source_dict['force'] + + if not os.path.exists(media): + mess = 'does NOT exists ! Continuing...' + self.logger.write_error(media, mess) + print media, mess + continue + else: + if not os.path.exists(dest) or force_mode != '': + mess = 'transcoding from %s:%s to %s:%s -> %s' \ + % (str(int(float(start_mn))), str(int(float(start_s))), str(int(float(end_mn))), str(int(float(end_s))), dest) + self.logger.write_info(media, mess) + command = self.transcode_command(media, str(start), str(duration), dest) + if not counter % 2: + while EnumProcesses() > 1: + # Only 2 threads for 2 cores and then sleeping + time.sleep(10) + os.system(command) + counter += 1 + + +if __name__ == '__main__': + if len(sys.argv) <= 2: + print """isp_tools.py +version : %s +author : %s +Dependencies : python, python-xlrd, ffmpeg, libmp3lame0 + +Usage : python isp_trans.py /path/to/source_dir /path/to/transcoded_source_dir /path/to/log_file /path/to/watermark_image +""" % (version, author) + + else: + source_dir = sys.argv[-3] + dest_dir = sys.argv[-2] + log_file = sys.argv[-1] + i = ISPTrans(source_dir, dest_dir, log_file) + i.process() -- 2.39.5