Table of Contents
This is a detector of video shots based of PyAV.
It is strongly under construction.
Nowadays, the main purpose of it is to visualize different methods of shot detection and near duplicate video retrieval.
It works both for Python 2.7 and Python 3.4.
Check this link anaconda.org/w495/shot-detector
conda install shot-detector -c w495
Check this link pypi/shot-detector
pip install shot-detector
- Note:
- pip installation likely will not work properly due to PyAV is depends on platform.
It uses conda as package manager. So to install it should run commands:
Create new environment and install requirements from conda:
conda create --name shot-detector-3.4 \ --file ./requirements/py34/requirements-conda-explicit.txt
Activate your environment
source activate shot-detector-3.4
Install requirements from pip:
pip install -r ./requirements/py34/requirements-pip.txt
The same for Python 2.7:
Create new environment and install requirements from conda:
conda create --name shot-detector-2.7 \ --file ./requirements/py27/requirements-conda-explicit.txt
Activate your environment
source activate shot-detector-2.7
Install requirements from pip:
pip install -r ./requirements/py27/requirements-pip.txt
See Managing environments for more details.
python ./main.py -i /path/to/file/or/stream
Or
python -m shot_detector.tool -i /path/to/file/or/stream
Use -h
option to get help.
python ./main.py -h
Also check help file for this.
You can use any video-file or video-device as an input for the Shot Detector. But in some cases it is required to use on-the-fly video stream.
You can get video-stream from third-party source or generate it yourself. There are several ways to generate your own input video stream:
- from a file;
- from your camera;
- from your desktop;
- from a virtual device.
More over you can implement it with different schemes of streaming:
- point to point streaming;
- streaming with server (
ffserver
).
This is the simplest way to reproduce on-the-fly video stream. In this case you generate stream only for one reader. If you use your stream for the Shot Detector, you cannot check it without stopping the Shot Detector. But in this stream embodiment you wont deal with latency.
In this case we use RTP Streaming Protocol. The main limitation of it is that only one stream supported in the RTP muxer. So you can stream only video without audio or audio without video.
Create a SDP-file and RTP-stream with
ffmpeg
. For a file stream it looks like this:ffmpeg -re -i input-file.mp4 -an -f rtp rtp://127.0.0.1:1236 > file-stream.sdp
Where:
-re
— is a flag that makesffmpeg
read input at native frame rate. In this case it is used to simulate a stream from a device. Without this flag, your stream will be handled as a simple file. It is required only if you work with static file but not real stream.-i input-file.mp4
— is a name of input file.-an
— is a flag that makes ffmpeg ignore audio streams. The reason of this flag is that RTP doesn't support more than one stream. Moreover, if your file contains several video streams, your should choose one and remove odd video streams.-f rtp
— is an output format — RTP.rtp://127.0.0.1:1234
— an address for receiving stream of virtual device../file-stream.sdp
— is a is a stream session description file.
Check the
./file-stream.sdp
. In this case it contains following text:SDP: v=0 o=- 0 0 IN IP4 127.0.0.1 s=No Name c=IN IP4 127.0.0.1 t=0 0 a=tool:libavformat 55.33.1000 m=video 1234 RTP/AVP 96 b=AS:2000 a=rtpmap:96 MP4V-ES/90000 a=fmtp:96 profile-level-id=1
Check the stream. Run
ffplay
with./file-stream.sdp
as an arguments.ffplay ./file-stream.sdp
You get a window with video from your file-stream.
- More over you can use any another player that supports RTP. For
example:
mplayer ./file-stream.sdp
Stop
ffplay
and then use./file-stream.sdp
file name as input URI for the Shot Detector
Note: RTP uses UDP, so the receiver can start up any time, but you can get packet loss.
Create a SDP-file and RTP-stream with
ffmpeg
. For a virtual device it looks like this:ffmpeg -f lavfi -i mandelbrot -f rtp rtp://127.0.0.1:1234 > virtual-device.sdp
Where:
-f lavfi
— is format oflibavfilter
input virtual devices . This input device reads data from the open output pads of a libavfilter filtergraph.-i mandelbrot
— is a filter that draws the Mandelbrot set. Check Fancy Filtering Examples in FFmpeg documentaion for another filter types.-f rtp
— is an output format — RTP.rtp://127.0.0.1:1234
— an address for receiving stream of a virtual device../virtual-device.sdp
— is a stream session description file.
Use
virtual-device.sdp
as discussed above.
Create a SDP-file and RTP-stream with ffmpeg
. For a camera it looks
like this:
ffmpeg -f v4l2 -i /dev/video0 -f rtp rtp://127.0.0.1:1234 > camera.sdp
Where:
-f v4l2
— is an input device-format for a camera. The full name of it is — [video4linux2] (https://www.ffmpeg.org/ffmpeg-devices.html#video4linux2_002c-v4l2) It works only for linux. For another systems, please, check this page: [FFmpeg Streaming Guide] (https://trac.ffmpeg.org/wiki/StreamingGuide "Streaming Guide")-i /dev/video0
— is a path to device.-f rtp
— is an output format — RTP.rtp://127.0.0.1:1234
— an address for receiving camera's stream../camera.sdp
— is a file with a description of your stream session.
After that use camera.sdp
as discussed above.
For a Linux display ffmpeg-command looks like this:
ffmpeg -f x11grab -video_size wxga -i :0.0 -f rtp rtp://127.0.0.1:1234 > desktop.sdp
Where:
-f x11grab
— is an input format for a X11-display.-video_size wxga
— size of your display. In this case we use the full size of desktop. Check FFmpeg Capture/Desktop page for other options-i :0.0
— is a desktop name.-f rtp
— is an output formatrtp://127.0.0.1:1234
— an address for receiving camera's stream../desktop.sdp
— is a stream session description file.
After that use desktop.sdp
as discussed above.
With MPEG-TS you can generate both and audio and video.
In this case we use UDP. So, you still can get packet loss. They are likely to reveal if you stream via Internet.
Here is example for a camera. For another devices they are the same.
Start
ffmpeg
to generate MPEG-TS stream via udp.ffmpeg -f v4l2 -i /dev/video0 -f mpegts udp://127.0.0.1:1234
Where:
-f v4l2
— is an input device-format for a camera. It works only for linux. For another systems, please, check this page: FFmpeg Streaming Guide.-i /dev/video0
— is a path to device.-f mpegts
— is an output format — MPEG transport stream.udp://127.0.0.1:1234
— an address for receiving camera's stream.
Check it with
ffplay
:ffplay -fflags nobuffer udp://127.0.0.1:1234
Where:
-fflags nobuffer
— is a flag that makes ffplay don't cache input stream. We set it to reduce latency.
- Use
udp://127.0.0.1:1234
as input video URI for the Shot Detector. | More over, you can startffmpeg
and the Shot Detector in any order.
Note: The time in the Shot Detector is a time of a video stream.
Also you can use both video and audio.
ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -f mpegts udp://127.0.0.1:1234
Where:
-f alsa
— is an input device-format for a microphone.-i hw:0
— is a name of a microphone device. See Capture/ALSA for more details.
Another option is to use TCP connections for MPEG-TS streaming. In this case you don't get packet loss. But you should guarantee that a reader will be started before a writer. So, reader become a server and writer become a client.
For example:
Start
ffplay
as a serverffplay -fflags nobuffer tcp://127.0.0.1:1234?listen
Where:
-fflags nobuffer
— is a flag that makes ffplay don't cache input stream. We set it to reduce latency.tcp://127.0.0.1:1234?listen
— is a host for sending camera's stream whithlisten
option. A writer should send stream totcp://127.0.0.1:1234
.
Start
ffmpeg
as a clientffmpeg -f v4l2 -i /dev/video0 -f mpegts tcp://127.0.0.1:1234
Where:
-f v4l2
— is an input device-format for a camera. It works only for linux. For another systems, please, check this page: FFmpeg Streaming Guide.-i /dev/video0
— is a path to device.-f mpegts
— is an output format — MPEG transport stream.tcp://127.0.0.1:1234
— an address for sending camera's stream.
So, you can pass tcp://127.0.0.1:1234?listen
as an input video URI
for the Shot Detector. But you should start it before ffmpeg
, Do not
forget to stop ffplay
, before it.
In this scheme you send the video-stream to a server. And then any
client can get your stream from it. The simplest way to achive this is
to use ffserver
.
Start ffserver with certain configuration file.
sudo /usr/bin/ffserver -f ./etc/input/ffserver.conf
Check FFServer Configuration.
Send input stream to server.
For example, for linux-camera you should run:
ffmpeg -f v4l2 -i /dev/video0 -f alsa -i hw:0 -tune zerolatency http://localhost:8090/feed1.ffm
Where:
-f v4l2
— is an input device-format for a camera. It works only for linux. For another systems, please, check this page: FFmpeg Streaming Guide.-i /dev/video0
— is a path to device.-f alsa
— is an input device-format for a microphone.-i hw:0
— is a name of a microphone device. See Capture/ALSA for more details.-tune zerolatency
— is a flag that makesffmpeg
to change settings to minimize latency. This is not a flag of ffmpeg, this is H.264 option. See Encode/H.264 Choose a preset for more details.http://localhost:8090/feed1.ffm
— an address for sending camera's stream.
For desktop it is the same:
ffmpeg -f x11grab -i :0.0 -f alsa -i hw:0 -tune zerolatency http://localhost:8090/feed1.ffm
Check it with
ffplay
:ffplay -fflags nobuffer http://localhost:8090/live.flv
Where:
-fflags nobuffer
— is a flag that makes ffplay don't cache input stream. We set it to reduce latency.http://localhost:8090/live.flv
— is an address to get a video stream. It is specified inetc/input/ffserver.conf
.
Pass
http://localhost:8090/live.flv
as an input video URI for the Shot Detector. In this case you may not stopffplay
.
As for me it is the best way to simulate streaming for the Shot Detector.