Player

ffpyplayer.player

FFmpeg based media player

A FFmpeg based python media player. See MediaPlayer for details.

class ffpyplayer.player.MediaPlayer

Bases: object

An FFmpeg based media player.

Was originally ported from FFplay. Most options offered in FFplay is also available here.

The class provides a player interface to a media file. Video components of the file are returned with get_frame(). Audio is played directly using SDL. And subtitles are acquired either through the callback function (text subtitles only), or are overlaid directly using the subtitle filter.

Note

All strings that are passed to the program, e.g. filename will first be internally encoded using utf-8 before handing off to FFmpeg.

Note

If playing or even opening multiple audio files simultaneously SDL2_mixer is required. The audio parameters of the first audio file opened will set the audio output parameters for all the subsequent audio files opened until they are all closed and a new file is opened.

Parameters
filename: str

The filename or url of the media object. This can be physical files, remote files or even webcam name’s e.g. for direct show or Video4Linux webcams. The f specifier in ff_opts can be used to indicate the format needed to open the file (e.g. dshow).

callback: Function or ref to function or None

A function, which if not None will be called when a internal thread quits, when eof is reached (as determined by whichever is the main sync stream, audio or video), or when text subtitles are available. In future version it may be extended.

The function takes two parameters, selector, and value. selector can be one of:

eof:

When eof is reached. value is the empty string.

display_sub:

When a new subtitle string is available. value will be a 5-tuple of the form (text, fmt, pts, start, end). Where

text: is the unicode text fmt: is the subtitle format e.g. ‘ass’ pts: is the timestamp of the text start: is the time in video time when to start displaying the text end: is the time in video time when to end displaying the text

exceptions or thread exits:

In case of an exception by the internal audio, video, subtitle, or read threads, or when these threads exit, it is called with a value of the error message or an empty string when an error is not available.

The selector will be one of audio:error, audio:exit, video:error, video:exit, subtitle:error, subtitle:exit, read:error, or read:exit indicating which thread called and why.

Warning

This functions gets called from a second internal thread.

loglevel: str

The level of logs to emit. Defaults to 'trace'. Its value is one of the keys of loglevels.

Although log are also filtered globally according to the level of set_loglevel, this is applied first to quickly filter logs generated by this instance (it’s not applied to internal ffmpeg logs).

thread_lib: str

The threading library to use internally. Can be one of ‘SDL’ or ‘python’.

Warning

If the python threading library is used, care must be taken to delete the player before exiting python, otherwise it may hang. The reason is that the internal threads are created as non-daemon, consequently, when the python main thread exits, the internal threads will keep python alive. By deleting the player directly, the internal threads will be shut down before python exits.

audio_sink: str

Currently it must be ‘SDL’. Defaults to ‘SDL’.

lib_opts: dict

A dictionary of options that will be passed to the ffmpeg libraries, codecs, sws, swr, and formats when opening them. This accepts most of the options that can be passed to FFplay. Examples are “threads”:”auto”, “lowres”:”1” etc. Both the keywords and values must be strings. See Examples for lib_opts usage examples.

ff_opts: dict

A dictionary with options for the player. Following are the available options. Note, many options have identical names and meaning as in the FFplay options: www.ffmpeg.org/ffplay.html :

paused: bool

If True, the player will be in a paused state after creation, otherwise, it will immediately start playing. Defaults to False.

cpuflags: str

Similar to ffplay

max_alloc: int

Set the maximum size that may me allocated in one block.

infbuf: bool

If True, do not limit the input buffer size and read as much data as possible from the input as soon as possible. Enabled by default for realtime streams, where data may be dropped if not read in time. Use this option to enable infinite buffers for all inputs.

framedrop: bool

Drop video frames if video is out of sync. Enabled by default if the master clock (sync) is not set to video. Use this option to enable/disable frame dropping for all master clock sources.

loop: int

Loops movie playback <number> times. 0 means forever. Defaults to 1.

autoexit: bool

If True, the player stops on eof. Defaults to False.

lowres: int

low resolution decoding, 1-> 1/2 size, 2->1/4 size, defaults to zero.

drp: int

let decoder reorder pts 0=off 1=on -1=auto. Defaults to 0.

genpts: bool

Generate missing pts even if it requires parsing future frames, defaults to False.

fast: bool

Enable non-spec-compliant optimizations, defaults to False.

stats: bool

Print several playback statistics, in particular show the stream duration, the codec parameters, the current position in the stream and the audio/video synchronisation drift. Defaults to False.

pixel_format: str

Sets the pixel format. Note, this sets the format of the input file. For the output format see out_fmt.

t: float

Play only t seconds of the audio/video. Defaults to the full audio/video.

ss: float

Seek to pos ss into the file when starting. Note that in most formats it is not possible to seek exactly, so it will seek to the nearest seek point to ss. Defaults to the start of the file.

sync: str

Set the master clock to audio, video, or external (ext). Default is audio. The master clock is used to control audio-video synchronization. Most media players use audio as master clock, but in some cases (streaming or high quality broadcast) it is necessary to change that. Also, setting it to video can ensure the reproducibility of timestamps of video frames.

acodec, vcodec, and scodec: str

Forces a specific audio, video, and/or subtitle decoder. Defaults to None.

ast: str

Select the desired audio stream. If this option is not specified, the “best” audio stream is selected in the program of the already selected video stream. See https://ffmpeg.org/ffplay.html#Stream-specifiers-1 for the format.

vst: str

Select the desired video stream. If this option is not specified, the “best” video stream is selected. See https://ffmpeg.org/ffplay.html#Stream-specifiers-1 for the format.

sst: str

Select the desired subtitle stream. If this option is not specified, the “best” audio stream is selected in the program of the already selected video or audio stream. See https://ffmpeg.org/ffplay.html#Stream-specifiers-1 for the format.

an: bool

Disable audio. Default to False.

vn: bool

Disable video. Default to False.

sn: bool

Disable subtitle. Default to False.

f: str

Force the format to open the file with. E.g. dshow for webcams on windows. See Playing a webcam with DirectShow on windows for an example. Defaults to none specified.

vf: str or list of strings

The filtergraph(s) used to filter the video stream. A filtergraph is applied to the stream, and must have a single video input and a single video output. In the filtergraph, the input is associated to the label in, and the output to the label out. See the ffmpeg-filters manual for more information about the filtergraph syntax.

Examples are ‘crop=100:100’ to crop, ‘vflip’ to flip horizontally, ‘subtitles=filename’ to overlay subtitles from another media or text file etc. If a list of filters is specified, select_video_filter() can be used to select the desired filter.

CONFIG_AVFILTER must be True (the default) when compiling in order to use this. Defaults to no filters.

af: str

Similar to vf. However, unlike vf, af only accepts a single string filter and not a list of filters.

x: int

The desired width of the output frames returned by get_frame(). Accepts the same values as the width parameter of set_size().

y: int

The desired height of the output frames returned by get_frame(). Accepts the same values as the height parameter of set_size().

CONFIG_AVFILTER must be True (the default) when compiling in order to use this. Defaults to 0.

out_fmt: str

The desired pixel format for the data returned by get_frame(). Accepts the same value as set_output_pix_fmt() and can be one of ffpyplayer.tools.pix_fmts. Defaults to rgb24.

autorotate: bool

Whether to automatically rotate the video according to presentation metadata. Defaults to True.

volume: float

The default volume. A value between 0.0 - 1.0.

find_stream_info: bool

Read and decode the streams to fill missing information with heuristics. Defaults to True.

filter_threads: int

The number of filter threads per graph. Defaults to zero (determined by the number of available CPUs).

For example, a simple player:

from ffpyplayer.player import MediaPlayer
player = MediaPlayer(filename)
while 1:
    frame, val = player.get_frame()
    if val == 'eof':
        break
    elif frame is None:
        time.sleep(0.01)
    else:
        img, t = frame
        print val, t, img.get_pixel_format(), img.get_buffer_size()
        time.sleep(val)
# which prints
0.0 0.0 rgb24 (929280, 0, 0, 0)
0.0 0.0611284 rgb24 (929280, 0, 0, 0)
0.0411274433136 0.1222568 rgb24 (929280, 0, 0, 0)
0.122380971909 0.1833852 rgb24 (929280, 0, 0, 0)
0.121630907059 0.2445136 rgb24 (929280, 0, 0, 0)
...

See also Examples.

Warning

Most of the methods of this class are not thread safe. That is, they should not be called from different threads for the same instance without protecting them.

close_player(self)

Closes the player and all resources.

Warning

After calling this method, calling any other class method on this instance may result in a crash or program corruption.

get_frame(self, force_refresh=False, show=True, *args)

Retrieves the next available frame if ready.

The frame is returned as a ffpyplayer.pic.Image. If CONFIG_AVFILTER is True when compiling, or if the video pixel format is the same as the output pixel format, the Image returned is just a new reference to the internal buffers and no copying occurs (see ffpyplayer.pic.Image), otherwise the buffers are newly created and copied.

Parameters
force_refresh: bool

If True, a new instance of the last frame will be returned again. Defaults to False.

show: bool

If True a image is returned as normal, if False, no image will be returned, even when one is available. Can be useful if we just need the timestamps or when force_refresh to just get the timestamps. Defaults to True.

Returns

A 2-tuple of (frame, val) where

frame: is None or a 2-tuple val: is either ‘paused’, ‘eof’, or a float

If val is either 'paused' or 'eof' then frame is None.

Otherwise, if frame is not None, val is the realtime time from now one should wait before displaying this frame to the user to achieve a play rate of 1.0.

Finally, if frame is not None then it’s a 2-tuple of (image, pts) where:

image: The ffpyplayer.pic.Image instance containing

the frame. The size of the image can change because the output can be resized dynamically (see set_size()). If show was False, it will be None.

pts: The presentation timestamp of this frame. This is the time

when the frame should be displayed to the user in video time (i.e. not realtime).

Note

The audio plays at a normal play rate, independent of when and if this function is called. Therefore, ‘eof’ will only be received when the audio is complete, even if all the frames have been read (unless audio is disabled or sync is set to video). I.e. a None frame will be sent after all the frames have been read until eof.

For example, playing as soon as frames are read:

>>> while 1:
...     frame, val = player.get_frame()
...     if val == 'eof':
...         break
...     elif frame is None:
...         time.sleep(0.01)
...         print 'not ready'
...     else:
...         img, t = frame
...         print val, t, img
not ready
0.0 0.0 <ffpyplayer.pic.Image object at 0x023D17B0>
not ready
0.0351264476776 0.0611284 <ffpyplayer.pic.Image object at 0x023D1828>
0.096254825592 0.1222568 <ffpyplayer.pic.Image object at 0x02411800>
not ready
0.208511352539 0.1833852 <ffpyplayer.pic.Image object at 0x02411B70>

vs displaying frames at their proper times:

>>> while 1:
...     frame, val = player.get_frame()
...     if val == 'eof':
...         break
...     elif frame is None:
...         time.sleep(0.01)
...         print 'not ready'
...     else:
...         img, t = frame
...         print val, t, img
...         time.sleep(val)
not ready
0.0 0.0 <ffpyplayer.pic.Image object at 0x02411800>
not ready
0.0351274013519 0.0611284 <ffpyplayer.pic.Image object at 0x02411878>
0.0602538585663 0.1222568 <ffpyplayer.pic.Image object at 0x024118A0>
0.122507572174 0.1833852 <ffpyplayer.pic.Image object at 0x024118C8>
...
0.0607514381409 1.222568 <ffpyplayer.pic.Image object at 0x02411B70>
0.0618767738342 1.2836964 <ffpyplayer.pic.Image object at 0x02411B98>
0.0610010623932 1.3448248 <ffpyplayer.pic.Image object at 0x02411BC0>
0.0611264705658 1.4059532 <ffpyplayer.pic.Image object at 0x02411BE8>

Or when the output format is yuv420p:

>>> player = MediaPlayer(filename, callback=weakref.ref(callback),
... ff_opts={'out_fmt':'yuv420p'})
>>> while 1:
...     frame, val = player.get_frame()
...     if val == 'eof':
...         break
...     elif frame is None:
...         time.sleep(0.01)
...         print 'not ready'
...     else:
...         img, t = frame
...         print val, t, img.get_pixel_format(), img.get_buffer_size()
...         time.sleep(val)
...
0.0 0.0 yuv420p (309760, 77440, 77440, 0)
0.0361273288727 0.0611284 yuv420p (309760, 77440, 77440, 0)
0.0502526760101 0.1222568 yuv420p (309760, 77440, 77440, 0)
0.12150645256 0.1833852 yuv420p (309760, 77440, 77440, 0)
0.122756242752 0.2445136 yuv420p (309760, 77440, 77440, 0)
get_metadata(self)

Returns metadata of the file being played.

Returns

dict:

Media file metadata. e.g. frame_rate is reported as a numerator and denominator. src and sink video sizes correspond to the frame size of the original video, and the frames returned by get_frame(), respectively. src_pix_fmt is the pixel format of the original input stream. ‘aspect_ratio’ is the source to display aspect ratio as a numerator and denominator. Duration is the file duration and defaults to None until updated.

:

>>> print player.get_metadata()
{'duration': 71.972, 'sink_vid_size': (0, 0), 'src_vid_size':
 (704, 480), 'frame_rate': (13978, 583),
 'title': 'The Melancholy of Haruhi Suzumiya: Special Ending',
 'src_pix_fmt': 'yuv420p'}

Warning

The dictionary returned will have default values until the file is open and read. Because a second thread is created and used to read the file, when the constructor returns the dict might still have the default values.

After the first frame is read, the dictionary entries are correct with respect to the file metadata. Alternatively, you can wait until the desired parameter is updated from its default value. Note, the metadata dict will be updated even if the video is paused.

Note

Some paramteres can change as the streams are manipulated (e.g. the frame size and source format parameters).

get_mute(self)

Returns whether the player is muted.

get_output_pix_fmt(self)

Returns the pixel fmt in which output images are returned when calling get_frame.

You can set the output format by specifying out_fmt in ff_opts when creating this instance. Also, if avfilter is enabled, you can change it dynamically with set_output_pix_fmt().

>>> print(player.get_output_pix_fmt())
rgb24
get_pause(self)

Returns whether the player is paused.

get_programs(self)

Returns a list of available program IDs.

>>> print(player.get_programs())
[0, 1, 2, 3, 4]
get_pts(self)

Returns the elapsed play time.

Returns

float:

The amount of the time that the file has been playing. The time is from the clock used for the player (default is audio, see sync options). If the clock is based on video, it should correspond with the pts from get_frame.

get_volume(self)

Returns the volume of the audio.

Returns

float: A value between 0.0 - 1.0.

request_channel(self, stream_type, action=u'cycle', int requested_stream=-1)

Opens or closes a stream dynamically.

This function may result in seeking when opening a new stream.

Parameters
stream_type: str

The stream group on which to operate. Can be one of 'audio', 'video', or 'subtitle'.

action: str

The action to perform. Can be one of 'open', 'close', or 'cycle'. A value of ‘cycle’ will close the current stream and open the next stream in this group.

requested_stream: int

The stream to open next when action is 'cycle' or 'open'. If -1, the next stream will be opened. Otherwise, this stream will be attempted to be opened.

request_program(self, int requested_program)

Opens video, audio and subtitle streams associated with a program.

This closes all current streams and opens the first video, audio and subtitle streams found in the program.

Parameters
requested_program: int

The program ID.

seek(self, pts, relative=True, seek_by_bytes=u'auto', accurate=True)

Seeks in the current streams.

Seeks to the desired timepoint as close as possible while not exceeding that time.

Parameters
pts: float

The timestamp to seek to (in seconds).

relative: bool

Whether the pts parameter is interpreted as the time offset from the current stream position (can be negative if True).

seek_by_bytes: bool or 'auto'

Whether we seek based on the position in bytes or in time. In some instances seeking by bytes may be more accurate (don’t ask me which). If 'auto', the default, it is automatically decided based on the media.

accurate: bool

Whether to do finer seeking if we didn’t seek directly to the requested frame. This is likely to be slower because after the coarser seek, we have to walk through the frames until the requested frame is reached. If paused or we reached eof this is ignored. Defaults to True.

For example:

>>> print player.get_frame()[0][1]
1016.392

>>> player.seek(200., accurate=False)
>>> player.get_frame()
>>> print player.get_frame()[0][1]
1249.876

>>> player.seek(200, relative=False, accurate=False)
>>> player.get_frame()
>>> print player.get_frame()[0][1]
198.49

Note that it may take a few calls to get new frames after seeking.

seek_to_chapter(self, increment, accurate=True)

Seeks forwards or backwards (if negative) by increment chapters.

Parameters
increment: int

The number of chapters to seek forwards or backwards to.

accurate: bool

Whether to do finer seeking if we didn’t seek directly to the requested frame. This is likely to be slower because after the coarser seek, we have to walk through the frames until the requested frame is reached. Defaults to True.

select_video_filter(self, index=0)

Selects the video filter to use from among the list of filters passed with the ff_opts vf options.

set_mute(self, state)

Mutes or un-mutes the audio.

Parameters
state: bool

Whether to mute or unmute the audio.

set_output_pix_fmt(self, pix_fmt)

Sets the pixel fmt in which output images are returned when calling get_frame().

For example:

>>> player.set_output_pix_fmt('yuv420p')

sets the output format to use. This will only take effect on images that have not been queued yet so it may take a few calls to get_frame() to reflect the new pixel format.

Note

if CONFIG_AVFILTER was False when compiling, this function will raise an exception.

set_pause(self, state)

Pauses or un-pauses the file.

Parameters
state: bool

Whether to pause or un-pause the player.

set_size(self, int width=-1, int height=-1)

Dynamically sets the size of the frames returned by get_frame().

Parameters
width, height: int

The width and height of the output frames. A value of 0 will set that parameter to the source width/height. A value of -1 for one of the parameters, will result in a value of that parameter that maintains the original aspect ratio.

For example:

>>> print player.get_frame()[0][0].get_size()
(704, 480)

>>> player.set_size(200, 200)
>>> print player.get_frame()[0][0].get_size()
(704, 480)
>>> print player.get_frame()[0][0].get_size()
(704, 480)
>>> print player.get_frame()[0][0].get_size()
(704, 480)
>>> print player.get_frame()[0][0].get_size()
(200, 200)

>>> player.set_size(200, 0)
>>> print player.get_frame()[0][0].get_size()
(200, 200)
>>> print player.get_frame()[0][0].get_size()
(200, 200)
>>> print player.get_frame()[0][0].get_size()
(200, 480)

>>> player.set_size(200, -1)
>>> print player.get_frame()[0][0].get_size()
(200, 480)
>>> print player.get_frame()[0][0].get_size()
(200, 480)
>>> print player.get_frame()[0][0].get_size()
(200, 136)

Note, that it takes a few calls to flush the old frames.

Note

if CONFIG_AVFILTER was False when compiling, this function will raise an error.

set_volume(self, volume)

Sets the volume of the audio.

Parameters
volume: float

A value between 0.0 - 1.0.

toggle_pause(self)

Toggles the player’s pause state.