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 inff_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
, andvalue
.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)
. Wheretext: 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 ofaudio:error
,audio:exit
,video:error
,video:exit
,subtitle:error
,subtitle:exit
,read:error
, orread: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 ofloglevels
.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 toss
. 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, unlikevf
,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 ofset_size()
.- y: int
The desired height of the output frames returned by
get_frame()
. Accepts the same values as the height parameter ofset_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 asset_output_pix_fmt()
and can be one offfpyplayer.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 (seeffpyplayer.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'
thenframe
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
inff_opts
when creating this instance. Also, if avfilter is enabled, you can change it dynamically withset_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='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.