Проигрывание медиафайлов

proigryvanie mediafajlov Законченные системные программы

В этой главе у нас еще осталось немного места, поэтому закроем ее небольшим развлекательным примером. Обратили ли вы внимание, что в сценариях поиска в двух предыдущих разделах мы жестко определяли расширения имен текстовых и двоичных файлов? Такой подход вполне оправдан для деревьев каталогов, к которым мы применяли их, но в общем случае его нельзя назвать законченным или переносимым. Было бы лучше, если бы мы могли автоматически определять тип файла по его имени. Такую возможность предоставляет модуль mimetypes. В этом разделе мы будем использовать его при создании сценария, который будет пытаться запускать файлы, опираясь на их типы, и по ходу дела разработаем универсальные инструменты для открытия медиафайлов переносимым способом, с использованием специализированных или универсальных программ-проигрывателей.

Как мы уже видели, в Windows эта задача решается тривиально просто — функция os.startfile открывает файл, используя реестр Windows, где хранятся соответствия между расширениями имен файлов и программами для работы с ними. На других платформах можно либо запускать определенные программы-проигрыватели для каждого типа файлов, либо возвращаться к использованию веб-броузера по умолчанию, открывая файлы с помощью модуля webbrowser. Воплощение этих идей в программный код приводится в примере 6.23.

Пример 6.23. PP4E\System\Media\playfile.py

#!/usr/local/bin/python

############################################################################## Пытается проигрывать медиафайлы различных типов. Позволяет определять специализированные программы-проигрыватели вместо использования универсального приема открытия файла в веб-броузере. В текущем своем виде может не работать в вашей системе; для открытия аудиофайлов в Unix используются фильтры и команды, в Windows используется команда start, учитывающая ассоциации с расширениями имен файлов (то есть для открытия файлов .au, например, она может запустить проигрыватель аудиофайлов или веб-броузер). Настраивайте и расширяйте сценарий под свои потребности. Функция playknownfile предполагает, что вы знаете, какой тип медиафайла пытаетесь открыть, а функция playfile пробует определить тип файла автоматически, используя модуль mimetypes; обе они пробуют запустить вебброузер с помощью модуля webbrowser, если тип файла не удается определить. ##############################################################################

import os, sys, mimetypes, webbrowser

helpmsg = “””

Sorry: can’t find a media player for ‘%s’ on your system!

Add an entry for your system to the media player dictionary

for this type of file in playfile.py, or play the file manually.

def trace(*args): print(*args) # с разделяющими пробелами

############################################################################## # приемы проигрывания: универсальный и другие: дополните своими приемами

##############################################################################

class MediaTool:

def __init__(self, runtext=’’): self.runtext = runtext

def run(self, mediafile, **options): # options обычно игнорируется

fullpath = os.path.abspath(mediafile) # cwd может быть любым

self.open(fullpath, **options)

class Filter(MediaTool):

def open(self, mediafile, **ignored):

media = open(mediafile, ‘rb’)

player = os.popen(self.runtext, ‘w’) # запустить команду оболочки

player.write(media.read()) # отправить файл в stdin

class Cmdline(MediaTool):

def open(self, mediafile, **ignored):

cmdline = self.runtext % mediafile # запустить команду

os.system(cmdline) # использовать %s для имени файла

class Winstart(MediaTool): # использует реестр Windows

def open(self, mediafile, wait=False, **other): # позволяет дождаться


if not wait:

os.startfile(mediafile)

# окончания проигрывания файла # или os.system(‘start file’)


else

os.system(‘start /WAIT ‘ + mediafile) class Webbrowser(MediaTool):

# file:// требует указывать абсолютный путь

def open(self, mediafile, **options):

webbrowser.open_new(‘file://%s’ % mediafile, **options)

############################################################################## # медиа- и платформозависимые методы: измените или укажите один из имеющихся ############################################################################## # соответствия платформ и проигрывателей: измените!

audiotools = {

‘sunos5’: Filter(‘/usr/bin/audioplay’), # os.popen().write()

‘linux2’: Cmdline(‘cat %s > /dev/audio’), # по крайней мере в PDA Zaurus

‘sunos4’: Filter(‘/usr/demo/SOUND/play’), # да, даже такая древность!

‘win32’: Winstart() # startfile или system

#’win32’: Cmdline(‘start %s’)

} videotools = {

подпись: # pda zaurus
# предотвратить вывод окна dos
‘linux2’: Cmdline(‘tkcVideo_c700 %s’),

‘win32’: Winstart(),

}

подпись: mimetable = {‘audio’: audiotools,
 ‘video’: videotools,
 ‘image’: imagetools,
 ‘text’: texttools,


# таблица соответствия

 

application’: apptools}

 

подпись: # не-html текст: броузер


 

imagetools = {

‘linux2’

‘win32’: }

: Cmdline(‘zimager %s’), Winstart(),

#

PDA Zaurus

texttools =

{

 

 

‘linux2’

: Cmdline(‘vi %s’),

#

PDA Zaurus

‘win32’:

}

Cmdline(‘notepad %s’)

#

или попробовать PyEdit?

apptools = {

 

 

 

‘win32’:

Winstart()

#

doc, xls, и др.: используйте

 

 

#

на свой страх и риск!

}

##############################################################################

# интерфейсы высокого уровня

############################################################################## def trywebbrowser(filename, helpmsg=helpmsg, **options)

пытается открыть файл в веб-броузере

как последнее средство, если тип файла или платформы неизвестен, а также для файлов типа text/html


trace(‘trying browser’, filename)

try:

player = Webbrowser() # открыть в броузере

player.run(filename, **options)

except:

print(helpmsg % filename) # никакой из способов не работает

def playknownfile(filename, playertable={}, **options):

проигрывает медиафайл известного типа: использует программы-проигрыватели для данной платформы или запускает веб-броузер, если для этой платформы не определено ничего другого; принимает таблицу соответствий расширений и программ-проигрывателей

if sys.platform in playertable: # известный

playertable[sys.platform].run(filename, **options) # инструмент

else: # универсальный

trywebbrowser(filename, **options) # прием

def playfile(filename, mimetable=mimetable, **options)

проигрывает медиафайл любого типа: использует модуль mimetypes для определения типа медиафайла и таблицу соответствий между расширениями и программами-проигрывателями; запускает веб-броузер для файлов с типом text/html, с неизвестным типом и при отсутствии таблицы соответствий

contenttype, encoding = mimetypes.guess_type(filename) # проверить имя

if contenttype == None or encoding is not None: # не определяется

contenttype = ‘?/?’ # возм. .txt.gz

maintype, subtype = contenttype.split(‘/’, 1) # ‘image/jpeg’

if maintype == ‘text’ and subtype == ‘html’:

trywebbrowser(filename, **options) # спец. случай

elif maintype in mimetable:

playknownfile(filename, mimetable[maintype], **options) # по таблице else:

trywebbrowser(filename, **options) # другие типы

##############################################################################

# программный код самопроверки

##############################################################################

if __name__ == ‘__main__’:

#   тип медиафайла известен

playknownfile(‘sousa.au’, audiotools, wait=True)

playknownfile(‘ora-pp3e.gif’, imagetools, wait=True)

playknownfile(‘ora-lp4e.jpg’, imagetools)

#   тип медиафайла определяется

input(‘Stop players and press Enter’)

playfile(‘ora-lp4e.jpg’) # image/jpeg

подпись: # image/gif
# text/html
# text/html
# text/plain
# app
# app
# audio/basic
# приостановиться, если
# сценарий запущен щелчком мыши
playfile(‘ora-pp3e.gif’)

playfile(‘priorcalendar.html’)

playfile(‘lp4e-preface-preview.html’) playfile(‘lp-code-readme.txt’)

playfile(‘spam.doc’)

playfile(‘spreadsheet.xls’) playfile(‘sousa.au’, wait=True) input(‘Done’)

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

Инструменты запуска программ, используемые этим сценарием, мы видели в предыдущих главах. Основным новшеством в этом сценарии является использование новых модулей: модуль webbrowser используется для открытия некоторых файлов в локальном веб-броузере, а модуль mimetypes применяется для определения типов медиафайлов по их именам. Поскольку они являются основой этого сценария, коротко познакомимся с ними, прежде чем запускать сценарий.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий