LINUX.ORG.RU

Запуск mplayer из-под X11 в скрипте Python

 , , , ,


0

2

Собственно сабж. Исходное оборудование:Banana Pi с подключенным по SPI считывателем RFID и монитором по HDMI. Установленная ОС:Lubuntu с LXDE.

Нужно было сделать, чтобы в зависимости от приложенной метки запускался тот или иной участок одного большого видеофайла. Для этого я родил скрипт Python, в котором через subprocess.Popen запускается mplayer в slave-режиме; дальше в бесконечном цикле скрипт опрашивает SPI и если находится одна из разрешенных меток, то стартует видео с определённой секунды в открытом mplayer-е на определённое время (почему не несколько видео фалов, а один большой? потому что критически важен абсолютно бесшовный переход между фрагментами, а mplayer некрасиво моргает рамкой окошка в случае использования фрагментов).

И вот собственно остался последний этап: нужно сделать, чтобы все это добро автозапускалось при старте системы. Вот тут-то и начались проблемы. Сначала я пытался запускать скрипт Python из скрипта bash, добавленного в автозапуск, однако сталкивался с тем, что видео запускалось с нарушением соотношения сторон и жутко тормозило при воспроизведении. В ходе анализа вывода консоли стало понятно, что mplayer не может найти видеовыход X11 и запускает с какими-то ограничениями через SDL. Т.е. bash-скрипт запускался не через tty7, в котором запущен xserver, а через tty1, в котором голая консоль. Начал пробовать запускать из bash-скрипта просто видео с различными ручными параметрами видеовывода - бесполезно. Потом я нашел в сети совет: прописать содержимое bash-скрипта в /etc/xdg/lxsession/Lubuntu/autostart. После этого видео стало корректно запускаться из-под X11. На радостях прописываю путь к своему Python-скрипту туда же - команда запуска mplayer в Python-скрипте опять идёт в tty1 и видео опять запускается абы как.

Вопрос: как из Python-скрипта адресовать в X11(который запущен в tty7) команду запуска mplayer? Или может возможно обратиться из Python-скрипта к экземпляру mplayer, который не создавался через этот скрипт (при помощи subprocess.Popen)? Помогите советом, заранее спасибо!

Потом я нашел в сети совет: прописать содержимое bash-скрипта в /etc/xdg/lxsession/Lubuntu/autostart. После этого видео стало корректно запускаться из-под X11. На радостях прописываю путь к своему Python-скрипту туда же - команда запуска mplayer в Python-скрипте опять идёт в tty1 и видео опять запускается абы как.

переменные окружения у тебя передаются в mplayer? DISPLAY в частности.

Novel ★★★★ ()
Ответ на: комментарий от true_admin

куда добавить?

Запускаю mplayer в Python так:

os.popen("sudo modprobe spi-sun7i")
file_name="/media/quest/pr_xvid.mp4" #filename
cmd =['mplayer','-fs','-nocorrect-pts','-lavdopts','threads=2','-slave','-quiet',file_name] #keys of mplayer
p = subprocess.Popen(cmd, stdin=subprocess.PIPE) #create subprocess of mplayer

Перед этим в этом же скрипте я прописал

os.popen("export DISPLAY:=0.0")

и вроде не работает :(

lavrik ()
Ответ на: комментарий от lavrik

и вроде не работает

и не должно, ты в popen запускаешь новый процесс (bash?) в котором выставляешь DISPLAY. Для родительского процесса это ничего не меняет.

Короче, некогда объяснять, делай вот так: http://stackoverflow.com/questions/5971312/how-to-set-environment-variables-i...

Кстати, shlex.split() умеет разбивать команду на токены, это удобно.

true_admin ★★★★★ ()
Ответ на: комментарий от lavrik
>>> subprocess.Popen(["mpv", "http://fs.to/get/dl/64z34id5spvaiczoib6toto92.0.1139013157.974127405.1458939192/Second.Chance.s01e10.WEBDL.1080p.NewStudio.mkv"], env=dict(os.environ, DISPLAY=":0"))
<subprocess.Popen object at 0x7f76ce5c7650>
>>> Playing: http://fs.to/get/dl/64z34id5spvaiczoib6toto92.0.1139013157.974127405.1458939192/Second.Chance.s01e10.WEBDL.1080p.NewStudio.mkv
 (+) Video --vid=1 (*) (h264)
 (+) Audio --aid=1 --alang=rus (*) 'NewStudio.TV' (ac3)
     Audio --aid=2 --alang=eng (ac3)
AO: [pulse] 48000Hz stereo 2ch float
Using hardware decoding (vdpau).
VO: [vdpau] 1920x1080 vdpau
[vo/vdpau] Compositing window manager detected. Assuming timing info is inaccurate.
AV: 00:00:00 / 00:44:41 (0%) A-V:  0.000 Cache:  3s+6KB
KeyboardInterrupt

У меня вот так взлетело без каких-либо проблем. Запускал с телефона по ssh, с пустым DISPLAY.

NeverLoved ★★★★★ ()
Ответ на: комментарий от true_admin

Перестал вообще запускаться чего-то скрипт....

в автозапуске lxde прописал

@sudo python /SPI-Py/MFRC622-python/Read.py

этот же текст когда ввожу ручками все работает, а на автозапуске нет...

lavrik ()
Ответ на: комментарий от true_admin

В файле автозапуска все записи такого вида:

@lxpanel --profile LXDE
@pcmanfm --desktop --profile LXDE
@lxterminal
@leafpad
@xscreensaver -no-splash@

Прописывал туда

@mplayer -fs /media/quest/pr_xvid.mp4

и все запускается. А вот питон не хочет :(

lavrik ()
Ответ на: комментарий от lavrik

If a line starts with @, and the command following it crashes, the command is automatically re-executed

Тебе именно такое поведение нужно?

По поводу логов — хз. Я могу только посоветовать запускать через strace и смотреть там. Например:

(без @)
strace -s 256 -f -o /tmp/strace mplayer ...

Лог можешь выложить где-нить и показать нам. Только осторожно, туда попадает личная инфа типа твой /etc/passwd, название хоста, путь до хомяка, и вообще все файлы что mplayer читает на старте. И ты можешь удивиться сколько всего оно читает.

Либо можешь сам покроптеть. Ещё бы ты скрипт целиком показал. Возможно, проблема тривиальна.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Да, автозапуск при краше мне тоже нужен.

Вот весь скрипт, лог потом поищу

#!/usr/bin/env python
# -*- coding: utf8 -*-
#How to stop script: Press CTRL+C 

import RPi.GPIO as GPIO
import MFRC522
import signal
import os
import time
import subprocess

#Enable SPI driver
#os.popen("sudo modprobe spi-sun7i")
continue_reading = True

# Capture SIGINT for cleanup when the script is aborted
def end_read(signal,frame):
    global continue_reading
    continue_reading = False
    GPIO.cleanup()

# Hook the SIGINT
signal.signal(signal.SIGINT, end_read)

# Create an object of the class MFRC522
MIFAREReader = MFRC522.MFRC522()

flag = 0  #check playing video


file_name="/media/quest/pr_xvid.mp4" #filename
cmd =['sudo','mplayer','-fs','-nocorrect-pts','-lavdopts','threads=2','-slave','-quiet',file_name] #keys of mplayer
p = subprocess.Popen(cmd, stdin=subprocess.PIPE) #create subprocess of mplayer
p.stdin.write("osd 0\n") #disable osd out
p.stdin.write("pause\n") #pause video by default

# This loop keeps checking for chips. If one is near it will get the UID and authenticate
while continue_reading:
    
    # Scan for cards    
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)   
    
    # Get the UID of the card
    if status == MIFAREReader.MI_OK:
	(status,uid) = MIFAREReader.MFRC522_Anticoll()
    # If we have the UID, continue
	# TAG 1
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="1632311660":#Number of tag
		#print ("We have 1 tag!")
		if flag==0:
			flag=1 #set flag of playing video 	
			p.stdin.write('seek 0 2\n') #from x second
			time.sleep(4) #for y second
			p.stdin.write('pause\n') #pause at end
			flag=0 #reset flag of playing video
	# TAG 2
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="1632511630":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 10 2\n')
			time.sleep(3)
			p.stdin.write('pause\n')
			flag=0
	# TAG 3
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="20193254229":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 20 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0		
	# TAG 4
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="1952311630":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 30 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0
	# TAG 5
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="1152241670":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 40 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0
	# TAG 6
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="5127962":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 50 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0
	# TAG 7
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="9963672":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 60 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0
	# TAG 8
	if str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])=="762413543":
		if flag==0:
			flag=1 	
			p.stdin.write('seek 70 2\n')
			time.sleep(4)
			#p.stdin.write('seek 4 2\n')
			p.stdin.write('pause\n')
			flag=0

lavrik ()
Ответ на: комментарий от lavrik

почему ты mplayer через sudo запускаешь? Ну и тебе не нужно вычислять str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3]) в каждом if. сделай это один раз в начале цикла. Что-то вроде str(uid) или str(uid[:4]), я хз что такое uid.

true_admin ★★★★★ ()
Ответ на: комментарий от arson

Такой вариант не сработал почему-то. Привожу конкретно мой код:

mkfifo /home/bananapi/fifos/mplayer
mplayer -nocorrect-pts -lavdopts threads=2 -input file=/home/bananapi/fifos/mplayer /media/quest/pr_xvid.mp4
echo "seek 30 2" > /home/bananapi/fifos/mplayer
Еще пробовал дописывать -slave и тоже не помогло. Создаваемый fifo файл в директории проверил, есть.

lavrik ()

Не знаю, актуально ли, но может быть есть смысл не запускать иксы сразу, а запускать mplayer как-то так:

xinit mplayer -- :1

(но, нужно будет еще какие-то разрешения добавить для иксов, не помню точно какие, погуглить надо)

irr123 ()
Ответ на: комментарий от lavrik

Да что в ubuntu-е mplayer-а новее нету?! Неверю.
Качни с сайта mplayer-а 1.3 и скомпилируй, благо у него в обязательных зависимостях только yasm (ffmpeg встроен).
Не знаю правда как там с кодеками под Allwinner.

arson ★★★★★ ()
Ответ на: комментарий от arson

Сделал как вы предложили, результат удручающий:

make[1]: *** [libavcodec/libxvid.o] Error 1
make[1]: Leaving directory `/home/bananapi/MPlayer-1.3.0/ffmpeg'
make: *** [ffmpeg/libavcodec/libavcodec.a] Error 2

C svn - то же самое.

lavrik ()