diff --git a/README.md b/README.md index a162edc..d993d52 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,44 @@ # PeerTube Performances Test Kit -Scripts to generate video files and live streams for performance testing of PeerTube \ No newline at end of file +Scripts to generate video files and live streams for performance testing of PeerTube + +## Dependencies +These scripts rely on ffmpeg to generate the videos files and RTMP streams. +Tested with ffmpeg versions: +- 4.1.6 +- 4.2.4 + +# Mains scripts +There are 4 main scripts : +- gen_pattern_sine.sh + generate video file with static pattern, time overlay (seconds elapsed from start) and sine wave stereo audio +- gen_random_noise.sh : + generate video file with random video, time overlay (seconds elapsed from start and local timestamp) and sine wave stereo audio +- stream_pattern_sine.sh : + send live stream and save a copy to file with static pattern, time overlay (seconds from start) and sine wave audio +- stream_random_noise.sh : + send live stream and save a copy to file with random video, time overlay (seconds elapsed from start and local timestamp) and sine wave audio + +Run the scripts with no paramters for help. + +The "random_noise" scripts are designed to produce video streams that are very hard to encode. These are to test worst case scenarii + +The "pattern_sine" scripts produce video streams that are lighter to process (use less CPU to encode on peertube side) and compress to a smaller size. + +# Helper scripts +The other scripts are helpers that are just sortcuts to call the main scripts with some pre-devfined parameters values. The names of these scripts should be self explanatory : + +- gen_pattern_1080p_60s.sh +- gen_pattern_720p_60s.sh +- gen_random_1080p_60s.sh +- gen_random_720p_60s.sh +- stream_pattern_1080p_300s.sh +- stream_pattern_1080p_3600s.sh +- stream_pattern_720p_300s.sh +- stream_pattern_720p_3600s.sh +- stream_random_1080p_300s.sh +- stream_random_1080p_3600s.sh +- stream_random_720p_300s.sh +- stream_random_720p_3600s.sh + + diff --git a/gen_pattern_1080p_60s.sh b/gen_pattern_1080p_60s.sh new file mode 100755 index 0000000..a455861 --- /dev/null +++ b/gen_pattern_1080p_60s.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./gen_pattern_sine.sh 60 1920x1080 6144 160 diff --git a/gen_pattern_720p_60s.sh b/gen_pattern_720p_60s.sh new file mode 100755 index 0000000..e3a4955 --- /dev/null +++ b/gen_pattern_720p_60s.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./gen_pattern_sine.sh 60 1280x720 4096 160 diff --git a/gen_pattern_sine.sh b/gen_pattern_sine.sh new file mode 100755 index 0000000..7533d35 --- /dev/null +++ b/gen_pattern_sine.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +DURATION=300 +RESOLUTION=1280x720 +VBITRATE=4096 +ABITRATE=160 + +if [[ $# -lt 1 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "You need to pass at least the duration in seconds " >&2 + echo " " >&2 + echo "syntax: " >&2 + echo " $(basename $0) " >&2 + echo " " >&2 + echo "other parameters are optional and will default to the " >&2 + echo "values in the following example :" >&2 + echo " `basename $0` $DURATION $RESOLUTION $VBITRATE $ABITRATE" >&2 + exit 1 +fi + +if [[ ! -z "$1" ]] +then + DURATION="$1" +fi + +if [[ ! -z "$2" ]] +then + RESOLUTION="$2" +fi + +if [[ ! -z "$3" ]] +then + VBITRATE="$3" +fi + +BUFFERSIZE=$(echo "2*${VBITRATE}" | bc) + +if [[ ! -z "$4" ]] +then + ABITRATE="$4" +fi + + +FILENAME=pattern-sine-${RESOLUTION}p-${DURATION}s-${VBITRATE}kbps-${ABITRATE}kbps.mkv +echo " " +echo Will generate image pattern with sine wave stream for $DURATION seconds to file : +echo $FILENAME +echo with : +echo "- $RESOLUTION resolution, " +echo "- $VBITRATE kbit/s constant video bitrate, " +echo "- $BUFFERSIZE kbit video buffer and " +echo "- $ABITRATE kbit/s audio bitrate" +echo " " + + +rm $FILENAME + +#-x264opts nal-hrd=cbr:force-cfr=1:vbv-bufsize=${BUFFERSIZE}:bitrate=${VBITRATE}:vbv-maxrate=${VBITRATE} \ + +ffmpeg \ +-loglevel level \ +-s ${RESOLUTION} \ +-loop 1 \ +-r 30 \ +-y \ +-ac 2 \ +-i Mire_1080p.png \ +-f lavfi \ +-i aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t)|0.1*sin(2*PI*(360+2.5/2)*t):sample_rate=48000" \ +-channel_layout stereo \ +-ar 48000 \ +-shortest \ +-pixel_format yuv420p \ +-filter_complex "[1:a]volume=-10dB;[0:v]scale='size=${RESOLUTION}',drawtext='font=FreeMono:text=%{pts}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=mod(floor(t/10+1)\,2)*mod(t*(w-text_w)/10\,w-text_w)+mod(floor(t/10)\,2)*(w-text_w-mod(t*(w-text_w)/10\,w-text_w)): y=h/2-3*text_h/2'" \ +-codec:v libx264 \ +-preset superfast \ +-x264opts bitrate=${VBITRATE} \ +-c:a aac -b:a ${ABITRATE}k \ +-t ${DURATION} \ +${FILENAME} diff --git a/gen_random_1080p_60s.sh b/gen_random_1080p_60s.sh new file mode 100755 index 0000000..da834d5 --- /dev/null +++ b/gen_random_1080p_60s.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./gen_random_noise.sh 60 1920x1080 6144 160 diff --git a/gen_random_720p_60s.sh b/gen_random_720p_60s.sh new file mode 100755 index 0000000..75e6b90 --- /dev/null +++ b/gen_random_720p_60s.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./gen_random_noise.sh 60 1280x720 4096 160 diff --git a/gen_random_noise.sh b/gen_random_noise.sh new file mode 100755 index 0000000..f6fdb26 --- /dev/null +++ b/gen_random_noise.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +DURATION=300 +RESOLUTION=1280x720 +VBITRATE=4096 +ABITRATE=160 + +if [[ $# -lt 1 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "You need to pass at least the duration in seconds " >&2 + echo " " >&2 + echo "syntax: " >&2 + echo " $(basename $0) " >&2 + echo " " >&2 + echo "other parameters are optional and will default to the " >&2 + echo "values in the following example :" >&2 + echo " `basename $0` $DURATION $RESOLUTION $VBITRATE $ABITRATE" >&2 + exit 1 +fi + +if [[ ! -z "$1" ]] +then + DURATION="$1" +fi + +if [[ ! -z "$2" ]] +then + RESOLUTION="$2" +fi + +if [[ ! -z "$3" ]] +then + VBITRATE="$3" +fi + +BUFFERSIZE=$(echo "2*${VBITRATE}" | bc) + +if [[ ! -z "$4" ]] +then + ABITRATE="$4" +fi + + +FILENAME=random-noise-${RESOLUTION}p-${DURATION}s-${VBITRATE}kbps-${ABITRATE}kbps.mkv +echo " " +echo Will generate random noise stream for $DURATION seconds to file : +echo $FILENAME +echo with : +echo "- $RESOLUTION resolution, " +echo "- $VBITRATE kbit/s constant video bitrate, " +echo "- $BUFFERSIZE kbit video buffer and " +echo "- $ABITRATE kbit/s audio bitrate" +echo " " + + +#-channel_layout stereo \ + +rm $FILENAME + +ffmpeg \ +-loglevel level \ +-f rawvideo \ +-video_size ${RESOLUTION} \ +-pixel_format yuv420p \ +-framerate 30 -i /dev/urandom \ +-ar 48000 \ +-ac 2 \ +-f s16le \ +-channel_layout stereo \ +-i /dev/urandom \ +-filter_complex "[1:a]volume=-30dB;[0:v]drawtext='font=FreeMono:text=%{pts}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=mod(floor(t/10+1)\,2)*mod(t*(w-text_w)/10\,w-text_w)+mod(floor(t/10)\,2)*(w-text_w-mod(t*(w-text_w)/10\,w-text_w)): y=h/2-3*text_h/2'" \ +-codec:v libx264 \ +-preset superfast \ +-x264opts nal-hrd=cbr:force-cfr=1:vbv-bufsize=${BUFFERSIZE}:bitrate=${VBITRATE}:vbv-maxrate=${VBITRATE} \ +-c:a aac -b:a ${ABITRATE}k \ +-t ${DURATION} \ +${FILENAME} diff --git a/stream_pattern_1080p_300s.sh b/stream_pattern_1080p_300s.sh new file mode 100755 index 0000000..b9bed9e --- /dev/null +++ b/stream_pattern_1080p_300s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_pattern_sine.sh $1 $2 300 1920x1080 3072 160 diff --git a/stream_pattern_1080p_3600s.sh b/stream_pattern_1080p_3600s.sh new file mode 100755 index 0000000..baf163e --- /dev/null +++ b/stream_pattern_1080p_3600s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_pattern_sine.sh $1 $2 3600 1920x1080 3072 160 diff --git a/stream_pattern_720p_300s.sh b/stream_pattern_720p_300s.sh new file mode 100755 index 0000000..ac187f4 --- /dev/null +++ b/stream_pattern_720p_300s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_pattern_sine.sh $1 $2 300 1280x720 2048 160 diff --git a/stream_pattern_720p_3600s.sh b/stream_pattern_720p_3600s.sh new file mode 100755 index 0000000..77947c8 --- /dev/null +++ b/stream_pattern_720p_3600s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_pattern_sine.sh $1 $2 3600 1280x720 2048 160 diff --git a/stream_pattern_sine.sh b/stream_pattern_sine.sh new file mode 100755 index 0000000..ebc0332 --- /dev/null +++ b/stream_pattern_sine.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +DURATION=300 +RESOLUTION=1280x720 +VBITRATE=4096 +ABITRATE=160 + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "You need to pass at least the PeerTube server name as the " >&2 + echo "first parameter and the streaming key as the second" >&2 + echo " " >&2 + echo "syntax: " >&2 + echo " $(basename $0) " >&2 + echo " " >&2 + echo "other parameters are optional and will default to the " >&2 + echo "values in the following example :" >&2 + echo " `basename $0` tube.example.com 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb $DURATION $RESOLUTION $VBITRATE $ABITRATE" >&2 + exit 1 +fi + +URL=rtmp://$1:1935/live/$2 + +if [[ ! -z "$3" ]] +then + DURATION="$3" +fi + +if [[ ! -z "$4" ]] +then + RESOLUTION="$4" +fi + +if [[ ! -z "$5" ]] +then + VBITRATE="$5" +fi + +BUFFERSIZE=$(echo "2*${VBITRATE}" | bc) + +if [[ ! -z "$6" ]] +then + ABITRATE="$6" +fi + +FILENAME=live-random-${1}-${RESOLUTION}p-${DURATION}s-${VBITRATE}kbps-${ABITRATE}kbps-${2}.mkv +echo " " +echo Will stream to $URL for $DURATION seconds +echo and save a copy of the data sent to the peertube server to file : +echo $FILENAME +echo with : +echo "- $RESOLUTION resolution, " +echo "- $VBITRATE kbit/s constant video bitrate, " +echo "- $BUFFERSIZE kbit video buffer and " +echo "- $ABITRATE kbit/s audio bitrate" +echo " " +$ + +#-x264opts nal-hrd=cbr:force-cfr=1:vbv-bufsize=${BUFFERSIZE}:bitrate=${VBITRATE}:vbv-maxrate=${VBITRATE} \ +#-shortest \ + +ffmpeg \ +-loglevel level \ +-s ${RESOLUTION} \ +-loop 1 \ +-r 30 \ +-y \ +-ac 2 \ +-i Mire_1080p.png \ +-re \ +-f lavfi \ +-i aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t)|0.1*sin(2*PI*(360+2.5/2)*t):sample_rate=48000" \ +-channel_layout stereo \ +-ar 48000 \ +-pixel_format yuv420p \ +-filter_complex "[1:a]volume=-10dB;[0:v]scale='size=${RESOLUTION}',drawtext='font=FreeMono:text=%{pts}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=mod(floor(t/10+1)\,2)*mod(t*(w-text_w)/10\,w-text_w)+mod(floor(t/10)\,2)*(w-text_w-mod(t*(w-text_w)/10\,w-text_w)): y=h/2-3*text_h/2', drawtext='font=FreeMono:text=%{localtime}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=(w-text_w)/2: y=h/2+3*text_h/2'" \ +-codec:v libx264 \ +-preset superfast \ +-x264opts nal-hrd=cbr:force-cfr=1:vbv-bufsize=${BUFFERSIZE}:bitrate=${VBITRATE}:vbv-maxrate=${VBITRATE} \ +-c:a aac -b:a ${ABITRATE}k \ +-t ${DURATION} \ +-flags +global_header \ +-f tee -map 0:v -map 1:a "[f=matroska]${FILENAME}|[f=flv]${URL}" diff --git a/stream_random_1080p_300s.sh b/stream_random_1080p_300s.sh new file mode 100755 index 0000000..976bdd9 --- /dev/null +++ b/stream_random_1080p_300s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_random_noise.sh $1 $2 300 1920x1080 6144 160 diff --git a/stream_random_1080p_3600s.sh b/stream_random_1080p_3600s.sh new file mode 100755 index 0000000..85445e9 --- /dev/null +++ b/stream_random_1080p_3600s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_random_noise.sh $1 $2 3600 1920x1080 6144 160 diff --git a/stream_random_720p_300s.sh b/stream_random_720p_300s.sh new file mode 100755 index 0000000..9dfaaaf --- /dev/null +++ b/stream_random_720p_300s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_random_noise.sh $1 $2 300 1280x720 4096 160 diff --git a/stream_random_720p_3600s.sh b/stream_random_720p_3600s.sh new file mode 100755 index 0000000..7112f1a --- /dev/null +++ b/stream_random_720p_3600s.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "you need to pass the peertubeserver name as the fisrt argument" >&2 + echo "and the streaming key as the second argument" >&2 + echo "expl: `basename $0` sub.domain.tld 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb" >&2 + exit 1 +fi + +./stream_random_noise.sh $1 $2 3600 1280x720 4096 160 diff --git a/stream_random_noise.sh b/stream_random_noise.sh new file mode 100755 index 0000000..e43b411 --- /dev/null +++ b/stream_random_noise.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +DURATION=300 +RESOLUTION=1280x720 +VBITRATE=4096 +ABITRATE=160 + +if [[ $# -lt 2 ]] ; then + echo "Not enough arguments supplied" >&2 + echo "You need to pass at least the PeerTube server name as the " >&2 + echo "first parameter and the streaming key as the second" >&2 + echo " " >&2 + echo "syntax: " >&2 + echo " $(basename $0) " >&2 + echo " " >&2 + echo "other parameters are optional and will default to the " >&2 + echo "values in the following example :" >&2 + echo " `basename $0` tube.example.com 69ac2d29-eba4-4d5f-a3a6-6047e6768ffb $DURATION $RESOLUTION $VBITRATE $ABITRATE" >&2 + exit 1 +fi + +URL=rtmp://$1:1935/live/$2 + +if [[ ! -z "$3" ]] +then + DURATION="$3" +fi + +if [[ ! -z "$4" ]] +then + RESOLUTION="$4" +fi + +if [[ ! -z "$5" ]] +then + VBITRATE="$5" +fi + +BUFFERSIZE=$(echo "2*${VBITRATE}" | bc) + +if [[ ! -z "$6" ]] +then + ABITRATE="$6" +fi + +FILENAME=live-random-${1}-${RESOLUTION}p-${DURATION}s-${VBITRATE}kbps-${ABITRATE}kbps-${2}.mkv +echo " " +echo Will stream to $URL for $DURATION seconds +echo and save a copy of the data sent to the peertube server to file : +echo $FILENAME +echo with : +echo "- $RESOLUTION resolution, " +echo "- $VBITRATE kbit/s constant video bitrate, " +echo "- $BUFFERSIZE kbit video buffer and " +echo "- $ABITRATE kbit/s audio bitrate" +echo " " +$ + +ffmpeg \ +-f rawvideo \ +-video_size ${RESOLUTION} \ +-pixel_format yuv420p \ +-framerate 30 -i /dev/urandom \ +-ar 48000 \ +-ac 2 \ +-f s16le \ +-re \ +-channel_layout stereo \ +-i /dev/urandom \ +-filter_complex "[1:a]volume=-30dB;[0:v]drawtext='font=FreeMono:text=%{pts}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=mod(floor(t/10+1)\,2)*mod(t*(w-text_w)/10\,w-text_w)+mod(floor(t/10)\,2)*(w-text_w-mod(t*(w-text_w)/10\,w-text_w)): y=h/2-3*text_h/2', drawtext='font=FreeMono:text=%{localtime}: fontcolor=white: fontsize=h/7: box=1: boxcolor=black@0.73: boxborderw=5: x=(w-text_w)/2: y=h/2+3*text_h/2'" \ +-codec:v libx264 \ +-preset superfast \ +-x264opts nal-hrd=cbr:force-cfr=1:vbv-bufsize=${BUFFERSIZE}:bitrate=${VBITRATE}:vbv-maxrate=${VBITRATE} \ +-c:a aac -b:a ${ABITRATE}k \ +-t ${DURATION} \ +-flags +global_header \ +-f tee -map 0:v -map 1:a "[f=matroska]${FILENAME}|[f=flv]${URL}"