KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Python interface for omxplayer now working (I hope)

Sun Jul 08, 2012 11:09 am

After a few weeks of trial and error I have produced a simple python interface for omxplayer. It can be used as a stand alone program or can be integrated into a more sophisticated program. It works on the couple of tracks I have tried, hopefully it will work for you.

Code is here https://github.com/KenT2/pyomxplayer

Its based on the ideas in this thread [url]http://www.raspberrypi.org/phpBB3/viewt ... t=7987[url], thanks everyone for the tips.
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

BenWiley4000
Posts: 100
Joined: Sun Jun 24, 2012 1:36 am

Re: Python interface for omxplayer now working (I hope)

Sun Jul 08, 2012 6:49 pm

I tested it out-- when I tell it the name of the file I want, it pretends I didn't give it a file and it keeps asking again. It understands "bye" though, so that's good I guess. Also, since I haven't tested it with an actual file, I can't confirm this, but since it asks "HDMI or local" output at the beginning, I wonder if that refers to sound or video or both. If I select HDMI, will it route the sound to HDMI? If I select "local", will it route the video to composite? Because I want neither of those to happen.

Cool idea-- I'd sort of rather see a GUI interface though at this point, since a lot of these ideas already exist in omxplayer and I've kind of been wanting a GUI for awhile.

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Sun Jul 08, 2012 7:28 pm

pyomxplayer is little more of a demonstration of how to interface omxplayer to python, which turned out to be quite a tricky thing to do. I added a simple user interface for test purposes. The code does not even have any error checking on user inputs, sorry.

The looping when you input a file name is probably because the file does not exist or it's in a format that omxplayer cannot play. In either case omxplayer quickly outputs some text and exits back to the 'Ask for a file' loop, unfortunately the text is not visible to the user (but I ought to look into how it might be). I have tried only mp4 and mp3 files, not sure what omxplayer will play. Have you changed the assignment to the variable videodir in the code to be the directory in which your video resides, ensuring its a path from root. If you change the variable debug to True then you will see the commands that are sent to omxplayer, you can check that the filename you want is being sent.

HDMI and local (analog) select sound outputs; video goes to whatever display you set up at boot time. All I do is pass the value input by the user to omxplayer.

I developed the interface because I want it for a video player for a visitor centre, controlled by push buttons, and only selecting from a few preset videos so I won't be developing a conventional media player GUI or improving the error checking. If you fancy doing that just copy the code and enjoy.
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

BenWiley4000
Posts: 100
Joined: Sun Jun 24, 2012 1:36 am

Re: Python interface for omxplayer now working (I hope)

Mon Jul 09, 2012 5:08 am

The problem is that my file definitely exists-- do I need to put the name in quotes? Is there some input format I'm unfamiliar with? I'm not really sure what's going on.

I just tested again. If I make the working directory the pyomxplayer directory and try using a file in another directory (which appropriate addressing, of course), it just loops. If I make the working directory the directory in which the video is located and use a long address for pyomxplayer.py, I get a different result with error output, but it still does not play the video. Here is that output:

traceback (most recent call last):
File "/home/pi/Downloads/pyomxplayer/pyomxplayer.py", line 186, in <module>
omx_play(omxoptions, videodir + track)
File "/home/pi/Downloads/pyomxplayer/pyomxplayer.py", line 110, in omx_play
proc=child_start(cwd)
File "/home/pi/Downloads/pyomxplayer/pyomxplayer.py", line 57, in child_start
stdin=subprocess.PIPE)
File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

I know this should be working because it works in normal omxplayer

ferrad
Posts: 3
Joined: Mon Jul 09, 2012 8:32 am

Re: Python interface for omxplayer now working (I hope)

Mon Jul 09, 2012 8:34 am

My error:

Traceback (most recent call last):
File "pyomxplayer.py", line 187, in <module>
omx_play(omxoptions, videodir )
File "pyomxplayer.py", line 111, in omx_play
proc=child_start(cwd)
File "pyomxplayer.py", line 57, in child_start
stdin=subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 13] Permission denied

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Mon Jul 09, 2012 12:17 pm

Thanks for your reports Ben and Ferrad. It's very useful to have your feedback.

I can recreate your error reports.

Ben , can you check that you have downloaded the file omxchild.sh and placed it in the same directory as pyomxplayer.py then make it executable as below.

Farrad. I think you need to make omxchild.sh executable. You can do this from the file manager by right clicking on the file >properties and then the permission tab.

Ben - use this method. "Make the working directory the pyomxplayer directory and use a file in another directory (which appropriate addressing, of course)" the other method does not work.
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

ferrad
Posts: 3
Joined: Mon Jul 09, 2012 8:32 am

Re: Python interface for omxplayer now working (I hope)

Mon Jul 09, 2012 12:57 pm

Super, it's working. Thank you.
Create a GUI will be easy.
The problem will be always on top mode.

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Mon Jul 09, 2012 4:14 pm

Glad it works. I've just uploaded version 1.03 which has some user input checking and sets omxchild.sh executable in the python program so it should be easier to use out of the box.
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

derdritte
Posts: 10
Joined: Fri Jul 06, 2012 10:58 pm

Re: Python interface for omxplayer now working (I hope)

Tue Jul 10, 2012 7:10 pm

Thanks KenT, this looks awesome :)

bmb6agb
Posts: 1
Joined: Mon Jul 16, 2012 4:23 pm

Re: Python interface for omxplayer now working (I hope)

Mon Jul 16, 2012 4:28 pm

I tried it with Debian Squeeze and Python 2.6.6.
I was able to stream videos to the Raspberry Pi from my AirStash using a base URL instead of a video directory.
The Python script reported that it couldn't find a file corresponding to the URL, but played it anyway.
+ and - didn't work, but q and bye worked fine.

kentaroyamada
Posts: 6
Joined: Mon Jun 25, 2012 11:39 am

Re: Python interface for omxplayer now working (I hope)

Wed Jul 18, 2012 1:10 pm

I have been trying various video format with this script.

All files plays ok with Python code, but it seems most of video doesn't take any commands ('p' to pause etc)

But I can get Bugs Bunny video to listen to commands. (test.h264 which is in /opt/vc/src/hello_pi/hello_video/ )

I am wondering what video format I should use to get pause, play etc working.

Any tips would be much appreciated!

Thanks

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Thu Jul 19, 2012 11:46 am

kentaroyamada wrote:I have been trying various video format with this script.

All files plays ok with Python code, but it seems most of video doesn't take any commands ('p' to pause etc)

But I can get Bugs Bunny video to listen to commands. (test.h264 which is in /opt/vc/src/hello_pi/hello_video/ )

I am wondering what video format I should use to get pause, play etc working.

Any tips would be much appreciated!

Thanks
I don't think the video format is your problem but the length of the video. omxplayer on wheezy beta has a bug in that it ignores commands after the end portion of the track has been put in the output buffer. I suspect the length (time) of the end portion is determined by the size of the buffer so a lower definition video or audio track will lose control sooner before the end. Unfortunately the update of omxplayer that is in wheezy raspbian has gone the other way and now cuts off the ends of tracks. :(
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working

Thu Jul 19, 2012 11:51 am

bmb6agb wrote:I tried it with Debian Squeeze and Python 2.6.6.
I was able to stream videos to the Raspberry Pi from my AirStash using a base URL instead of a video directory.
The Python script reported that it couldn't find a file corresponding to the URL, but played it anyway.
+ and - didn't work, but q and bye worked fine.
not finding a web url is a limitation of pyomxplayer. Its not a full featured player but a simple test harness for the demonstration of how to control omxplayer from python. You will need to modify the code of or remove check_input to get web based tracks to play.

+- were not implemented in the omxplayer. They are in wheezy raspbian but omxplayer is now broke in another way.
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Thu Jul 19, 2012 11:56 am

There is now an another python interface for omxplayer here. Looks a very nice implementation compared to my beginners effort.

https://github.com/jbaiter/pyomxplayer
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

User avatar
jbaiter
Posts: 13
Joined: Tue Jul 03, 2012 7:52 pm

Re: Python interface for omxplayer now working (I hope)

Thu Jul 19, 2012 2:01 pm

Thanks for mentioning it, KenT :-) Sorry for "stealing" the name, though :-/
I'll hopefully be pushing a new version to GitHub on the weekend that exposes the rest of the player's functionality, but I'm having trouble with rather high cpu usage when telling pexpect to watch stdout for more than one pattern.
It's very rough at the moment, though. If I knew C++, I'd try to make a library out of OMXPlayer that one could then link to from Python. This way, one could e.g. directly seek in the stream (as opposed to multiple 30sec/10m steps), set the volume, chapter, audio track directly (instead of doing it step by step through simulated keypresses). Another option could be to add a support for local sockets to OMXPlayer, so that it could be controlled via a simple protocol. And yet another one, implementing something similar to MPlayer's slave mode, where OMXPlayer accepts a number of commands with arguments from stdin, like "seek 150", where it would seek to position 02:30 in the current stream.

kentaroyamada
Posts: 6
Joined: Mon Jun 25, 2012 11:39 am

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 10:45 am

Hi I am new to Python.. I installed pythonplayer with pexpect..
Would anyone be able to provide a python code on how to use this script to play video?
Thanks!
KenT wrote:There is now an another python interface for omxplayer here. Looks a very nice implementation compared to my beginners effort.

https://github.com/jbaiter/pyomxplayer

User avatar
jbaiter
Posts: 13
Joined: Tue Jul 03, 2012 7:52 pm

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 12:51 pm

kentaroyamada wrote:Hi I am new to Python.. I installed pythonplayer with pexpect..
Would anyone be able to provide a python code on how to use this script to play video?
Thanks!
Did you take a look at the README.rst on the GitHub page? The 'Example' section should answer your question.
You just create an object from the class "OMXPlayer" and pass the filename as the first argument to the constructor. If you add "start_playback=True" as an additional argument, playback will start immediately after the object is created, otherwise you will have to call the "toggle_pause" method first.

kentaroyamada
Posts: 6
Joined: Mon Jun 25, 2012 11:39 am

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 1:06 pm

Sorry I am new to Python..
I copied an pasted below and named test.py
It doesn't seem to run..

>>> from pyomxplayer import OMXPlayer
>>> from pprint import pprint
>>> omx = OMXPlayer('kyx.mov')
>>> pprint(omx.__dict__)
{'_position_thread': <Thread(Thread-5, started 1089234032)>,
'_process': <pexpect.spawn object at 0x1a435d0>,
'audio': {'bps': 16,
'channels': 2,
'decoder': 'mp3',
'rate': 48000,
'streams': 1},
'chapters': 0,
'current_audio_stream': 1,
'current_volume': 0.0,
'paused': True,
'position': 0.0,
'subtitles': 0,
'subtitles_visible': False,
'video': {'decoder': 'omx-mpeg4',
'dimensions': (640, 272),
'fps': 23.976025,
'profile': 15,
'streams': 1}}
>>> omx.toggle_pause()
>>> omx.position
9.43
>>> omx.stop()

User avatar
jbaiter
Posts: 13
Joined: Tue Jul 03, 2012 7:52 pm

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 1:47 pm

Errmmmmm... The example is what you would enter (the stuff behind the ">>>") and see (the lines below each command) in the interactive interpreter. To put the code in a script, you would just take the code behind the ">>>" characters (not including them!) and paste that into a file.
I don't want to sound rude, but may I ask just how new you are to Python? I suggest you should at least have read the Python tutorial (or better, worked through Zed Shaw's "Learn Python the Hard Way") before attempting to write your own scripts.

kentaroyamada
Posts: 6
Joined: Mon Jun 25, 2012 11:39 am

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 2:29 pm

Thank you very much for this.
I studied Computer Science with Java, so I am new to this scripting ... ;)
I will find out what how interactive interpreter works, and how I can actually make a executable file..
I have been playing around with other pyomxplayer python script and it is a executable file, so I assumed all Python scripts are executable.

User avatar
jbaiter
Posts: 13
Joined: Tue Jul 03, 2012 7:52 pm

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 4:16 pm

kentaroyamada wrote:Thank you very much for this.
I studied Computer Science with Java, so I am new to this scripting ... ;)
Well, then the words "object", "constructor" and "method" should sound familiar enough to infer how the code is supposed to be run from the example and my explanation, even if you have never seen Python in your life ;-)
I will find out what how interactive interpreter works, and how I can actually make a executable file..
I have been playing around with other pyomxplayer python script and it is a executable file, so I assumed all Python scripts are executable.
I'm quite astonished that you got a CS degree without ever having used a REPL-interpreter or without learning anything about interpreted/scripting languages (hint: Python is a lot like Java in this respect, except that the interpreter handles the conversion to bytecode for you). There are no "executables" in Python, all you use are text-files that are opened and executed by the interpreter. Some of these are supposed to be run on their own, others (like this one) are intended to be used in other python scripts/programs (those are called "modules" in Python).

KenT
Posts: 758
Joined: Tue Jan 24, 2012 9:30 am
Location: Hertfordshire, UK
Contact: Website

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 7:34 pm

Johannes - I've been trying out your interface behind a little gui. One track plays OK, pauses etc. so I know its working however the other 2 tracks I have been trying fail with the errors below. I suspect the regular expression decoding is not coping with these non-standard outputs from omxplayer.

I include the output of omxplayer run at the command line followed by the error message from my bplayer program into which I have copied your code.

Code: Select all


a. This file worked OK

pi@raspberrypi ~/videos $ omxplayer -olocal xthresh.mp4
file : xthresh.mp4 reult 6 format mov,mp4,m4a,3gp,3g2,mj2 audio streams 1 video streams 1 chapters 0 subtitles 0
Video codec omx-h264 width 720 height 576 profile 77 fps 25.000000
Audio codec aac channels 2 samplerate 32000 bitspersample 16

have a nice day ;)

======================================================

b.

pi@raspberrypi ~/videos $ omxplayer -olocal cl1.mp4
file : cl1.mp4 reult 69 format mov,mp4,m4a,3gp,3g2,mj2 audio streams 1 video streams 1 chapters 0 subtitles 0
Invalid framerate 125, using forced 25fps and just trust timestamps
Video codec omx-h264 width 700 height 572 profile 77 fps 25.000000
Audio codec aac channels 2 samplerate 48000 bitspersample 16

This file failed with:

  File "bplayer.py", line 288, in start
    self.omx = OMXPlayer(self.selected_track_location, self.omx_options, start_playback=True)
  File "bplayer.py", line 57, in __init__
    video_props = self._VIDEOPROP_REXP.match(self._process.readline()).groups()
AttributeError: 'NoneType' object has no attribute 'groups'


======================================================

pi@raspberrypi ~/videos $ omxplayer -olocal 01.mp3
[mp3 @ 0x1b69f20] max_analyze_duration reached
[mp3 @ 0x1b69f20] Estimating duration from bitrate, this may be inaccurate
file : 01.mp3 reult 0 format mp3 audio streams 1 video streams 0 chapters 0 subtitles 0
Audio codec mp3 channels 2 samplerate 44100 bitspersample 16

This file fails with:

  File "bplayer.py", line 288, in start
    self.omx = OMXPlayer(self.selected_track_location, self.omx_options, start_playback=True)
  File "bplayer.py", line 53, in __init__
    file_props = self._FILEPROP_REXP.match(self._process.readline()).groups()
AttributeError: 'NoneType' object has no attribute 'groups'
Pi Presents - A toolkit to produce multi-media interactive display applications for museums, visitor centres, and more
Download from http://pipresents.wordpress.com

User avatar
jbaiter
Posts: 13
Joined: Tue Jul 03, 2012 7:52 pm

Re: Python interface for omxplayer now working (I hope)

Tue Jul 24, 2012 8:21 pm

Ah, I see. The current code expects the first lines to be audio and video properties, the line for invalid framerate obviously breaks that. I'll look into that, thanks for pointing that out!
Unfortunately I left my Pi at a friend's place and will only be getting it back tomorrow or the day after tomorrow, then I'll be able to test my new code.

ffodder
Posts: 1
Joined: Fri Aug 17, 2012 8:20 pm

Re: Python interface for omxplayer now working (I hope)

Fri Aug 17, 2012 8:49 pm

@KenT (or anyone else who has some thoughts on the subject!)

While I realize that there is an alternate method available for running omxplayer using python (provided by jbaiter), I am interested in continuing to use your method (external bash script) in a digital signage setup. (Which needs to support still images, in addition to video.)

However, I cannot, for the life of me, get a command sent through a named FIFO pipe to work on an image viewer. (I have tried both qiv and feh.)

Here is my code - based largely on yours:
child.sh

Code: Select all

#!/bin/sh
    read CC TT FF

    if [ $CC = "image" ]; then
        feh -F -Y $FF <$TT
        #qiv -f -i $FF <$TT
        exit
    elif [ $CC = "video" ]; then
        omxplayer -o local $FF <$TT
        exit
    fi
player.py:

Code: Select all

import sys
import subprocess
import time
import os

# SETTINGS
childPath = '/home/pi/child.sh'

# MAKE child.sh EXECUTABLE
os.system("chmod +x " + childPath)

# CREATE FIFO FOR COMMUNICATION TO PLAYER/VIEWERs
fifo1 = "/tmp/playercmd1"
if os.path.exists (fifo1): os.system("rm " + fifo1)
os.system("mkfifo " + fifo1)

# START CHILD PROCESS AND RETURN HANDLE
def startChildProc():
    proc=subprocess.Popen([childPath], shell=False, \
          stderr=subprocess.PIPE, \
          stdout=subprocess.PIPE, \
          stdin=subprocess.PIPE)
    
    # WAIT FOR CHILD TO START
    while proc.poll()!= None:
        time.sleep(0.1)
    return proc

# SEND FIFO COMMAND
def sendFifoCommand(char,fifo):
    command = "echo -n " + char + ">" + fifo
    os.system(command)

def displayItem(type, path, fifo):
    # SEND CHILD COMMAND
    def sendChildCommand (command, proc):
        proc.stdin.write(command)
    
    # START CHILD PROCESS
    proc = startChildProc()
    
    # SEND COMMAND TO CHILD PROCESS TO START VIDEO PLAYER
    if type == "video":
        sendChildCommand("video " + fifo + " " + path + "\n", proc)
        sendFifoCommand('.', fifo)
    
    # SEND COMMAND TO CHILD PROCESS TO START IMAGE VIEWER
    elif type == "image":
        sendChildCommand("image " + fifo + " " + path + "\n", proc)
        sendFifoCommand('.',fifo1)

while True:
    #displayItem("video", "/home/pi/1080p.mp4", fifo1)
    displayItem("image", "/home/pi/logo.jpg", fifo1)
    
    print "Wait for 10 seconds..."
    time.sleep(10)
    print "Send quit command..."
    sendFifoCommand('q',fifo1)

    break

print "Player Exiting..."
sys.exit()
In player.py, if I use the "displayItem("video", "/home/pi/1080p.mp4", fifo1)" line everything works as expected. But images don't work with either qiv or feh. In either case, the image viewer opens correctly, but never quits unless I manually enter the "q" key on my keyboard.

Any idea why?

I just noticed your comment about omxplayer not accepting commands after the video has finished loading so I tried it with a smaller video and sure enough, the above code only works for large videos.

I suspect that since the images are being loaded almost immediately that the same problem is occurring.

Could it be that the FIFO pipe is being closed prematurely for all external processes when using this method? (Rather than a bug in omxplayer?)

Any help and/or thoughts would be greatly appreciated!

ffodder

metamad
Posts: 1
Joined: Sun Dec 23, 2012 11:51 pm

Re: Python interface for omxplayer now working (I hope)

Mon Dec 24, 2012 1:11 am

jbaiter wrote:Ah, I see. The current code expects the first lines to be audio and video properties, the line for invalid framerate obviously breaks that. I'll look into that, thanks for pointing that out!
Unfortunately I left my Pi at a friend's place and will only be getting it back tomorrow or the day after tomorrow, then I'll be able to test my new code.
I also got this error:

Code: Select all

    video_props = self._VIDEOPROP_REXP.match(self._process.readline()).groups()
AttributeError: 'NoneType' object has no attribute 'groups'
These are the first four lines omxplayer (build date ~ 9/29/2012) prints out for me:

Code: Select all

file : test.avi result 2 format avi audio streams 1 video streams 1 chapters 0 subtitles 0
Aspect : num 1 den 1 aspect 2.352941 display aspect 1.500000
Video codec omx-mpeg4 width 640 height 272 profile 15 fps 25.000000
Audio codec mp3 channels 2 samplerate 48000 bitspersample 16
Looks like the issue is that the second line lists aspect properties, not video properties like jbater's code expects; and audio properties is the fourth line, not the third. So as a quick fix I added

Code: Select all

aspect_props = self._process.readline()
before the line

Code: Select all

video_props = self._VIDEOPROP_REXP.match(self._process.readline()).groups()

Return to “Graphics, sound and multimedia”