Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Безопасный запуск дочерних процессов, os.popen* or popen2.* ? 
:(
    Опции темы
@lex
Дата 12.10.2006, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 3.2.2004
Где: Москва

Репутация: нет
Всего: нет



Сразу рассмотрю на примере 

Есть некоторый видео файл. Требуется получить максимальное количество информации о нём. 
Найденое мною решение предполагает запуск MPlayer с параметрами
Цитата

mplayer -identify -vo null -ao null -slave -nocache путь_к_контенту

и парсинг его вывода...

Mplayer конечно замечательный плеер, но может периодически подвисать если ему дать какую нибудь бяку.
Вот этого требуется избежать.

Решение:
Код


import os.path
import sys,re
import Image,popen2
import time,threading,signal

class Oracle:
    MPLAYER_IDENTIFY_CMD="mplayer -identify -vo null -ao null -slave -nocache"

    ID_REGEXP_PATTERN=r'ID_[A-Z,_]*=.*'

    WAIT_BEFORE_INFO_KILL=5.0
    WAIT_BEFORE_SCREENSHOT_KILL=15.0

    def _getMplayerInfoOut(self,pathToSource):

        pList=(self.MPLAYER_IDENTIFY_CMD+' '+pathToSource).split()
        self._pid=0

        #print "params=",pList

        #create pipe object
        pipeObject=popen2.Popen4(pList)
        self._pid=pipeObject.pid

        #create kill timer
        self.killThread=threading.Timer(self.WAIT_BEFORE_INFO_KILL,self._killMplayer)
        self.killThread.start()

        #close pipe's stdin
        pipeObject.tochild.write('quit\n')
        pipeObject.tochild.close()

        #wait while mplayer finished or killed
        pipeObject.wait()
        #maybe we need to cancel killer
        self._pid=0
        self.killThread.cancel()

        #get mplayer out
        mplOut=pipeObject.fromchild.read()
        pipeObject.fromchild.close()

        return mplOut

    def _killMplayer(self):
        print "try exec mplayer killing"
        if self._pid:
            print "try kill mplayer pid:",self._pid
            os.kill(self._pid,signal.SIGINT)

    def _parseMplayerInfoOut(self,mplOut):
        idRegexp=re.compile(Oracle.ID_REGEXP_PATTERN)

        result={}
        for idString in idRegexp.findall(mplOut):
            name,value=idString.split('=')
            result[name[3:]]=value

        return result

    def readSourceInfo(self,pathToSource):
        mplOut=self._getMplayerInfoOut(pathToSource)
        result=self._parseMplayerInfoOut(mplOut)

        return result

if __name__=='__main__':
    o=Oracle()
    pathToSource=sys.argv[1]
    info=o.readSourceInfo(pathToSource)
    print info


результаты
Код

{'AUDIO_NCH': '2', 'DEMUXER': 'avi', 'AUDIO_FORMAT': '85', 'VIDEO_HEIGHT': '240', 'VIDEO_BITRATE': '312224', 'VIDEO_ID': '0', 'AUDIO_RATE': '22050', 'FILENAME': '/home/wizard/films/fallenart.avi', 'VIDEO_ASPECT': '0.0000', 'VIDEO_FORMAT': 'DIV3', 'LENGTH': '341.76', 'AUDIO_BITRATE': '80000', 'AUDIO_CODEC': 'mp3', 'VIDEO_FPS': '25.000', 'VIDEO_CODEC': 'ffdivx', 'VIDEO_WIDTH': '320', 'AUDIO_ID': '1'}


Это только пример работы с mplayer, анологично работаю с fehом, а с ним при частом запуске и всяк проблемы возникают, в подробности вдаваться не буду но факт в том, что использование unionfs+tmpfs  приводит к тому что он вываливется в непонятно состояние из которого вывести его давольнотаки праблемотично, помогает только перезагрузка  smile  ...

Вобщем есть ли какие предложения как сделать этот код "безопаснее" && надёжнее.

Это сообщение отредактировал(а) @lex - 12.10.2006, 08:32
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0396 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.