diff --git a/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress b/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress index 56e05f9..a4652ab 100644 --- a/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress +++ b/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress @@ -11,7 +11,7 @@ info: # @toDo: Ist es mit vorheriger Skalierung schneller, oder langsamer? videos/.forCompressing/%.trf: videos/.forCompressing/%.video $(FFMPEG) -i $^ \ - -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoFilterDenoise)$(ffmpegVideoFilterVidstabDetect):result="$@" \ + -filter:v $(ffmpegVideoFilterDeinterlace),$(ffmpegVideoScaleFilter),$(ffmpegVideoFilterVidstabDetect):result="$@" \ -f null \ - @@ -21,7 +21,7 @@ videos/.forCompressing/%.trf: videos/.forCompressing/%.video # kann. Wäre praktisch für eine leicht schnellere Verfügbarkeit. videos/.forCompressing/%.firstPassLog-0.log: videos/.forCompressing/%.video videos/.forCompressing/%.trf $(FFMPEG) -i $< \ - -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoFilterDenoise)$(ffmpegVideoFilterVidstabTransform):input="$(basename $<).trf",$(ffmpegVideoScaleFilter)unsharp=5:5:0.8:3:3:0.4 \ + -filter:v $(ffmpegVideoFilterDeinterlace),$(ffmpegVideoScaleFilter),$(ffmpegVideoFilterDenoise),$(ffmpegVideoFilterVidstabTransform):input="$(basename $<).trf",$(ffmpegVideoFilterUnsharp),$(ffmpegVideoScaleFilter) \ -codec:v $(VID_CODEC) \ -pass 1 \ -passlogfile "$(basename $<).firstPassLog" \ @@ -41,12 +41,12 @@ videos/.forCompressing/%.firstPassLog-0.log: videos/.forCompressing/%.video vide videos/webm/%.webm: videos/.forCompressing/%.video videos/.forCompressing/%.trf videos/.forCompressing/%.firstPassLog-0.log mkdir -p videos/webm $(FFMPEG) -i $< \ - -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoFilterDenoise)$(ffmpegVideoFilterVidstabTransform):input="$(basename $<).trf",$(ffmpegVideoScaleFilter)unsharp=5:5:0.8:3:3:0.4 \ + -filter:v $(ffmpegVideoFilterDeinterlace),$(ffmpegVideoScaleFilter),$(ffmpegVideoFilterDenoise),$(ffmpegVideoFilterVidstabTransform):input="$(basename $<).trf",$(ffmpegVideoFilterUnsharp) \ -codec:v $(VID_CODEC) \ -pass 2 \ -passlogfile "$(basename $<).firstPassLog" \ $(VID_CODEC_DEADLINE) \ - -b:v $(shell $(GET_VIDEO_DURATION_JSON) $<)k \ + -b:v $(shell $(getTargetParameter) $< videoBitrate)k \ -threads 1 \ -speed 0 \ -tile-columns 0 \ @@ -65,7 +65,9 @@ videos/thumbnails/%.png: videos/.forCompressing/%.video # $(FFMPEG) -i "$<" -vf $(ffmpegVideoScaleFilter)thumbnail -frames:v 1 "$@" # $(FFMPEG) -i "$<" -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoFilterDenoise)$(ffmpegVideoFilterVidstabTransform):input="$(basename $<).trf",$(ffmpegVideoScaleFilter)unsharp=5:5:0.8:3:3:0.4,thumbnail -frames:v 1 "$@" # $(FFMPEG) -i "$<" -aspect $(ffmpegDisplayAspectRatio) -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoScaleFilter)thumbnail -frames:v 1 "$@" - $(FFMPEG) -i "$<" -filter:v $(ffmpegVideoFilterDeinterlace)$(ffmpegVideoScaleFilter)thumbnail -frames:v 1 "$@" + $(FFMPEG) -i "$<" \ + -filter:v $(ffmpegVideoFilterDeinterlace),$(ffmpegVideoScaleFilter),thumbnail \ + -frames:v 1 "$@" videos/thumbnails/%.jpg: videos/thumbnails/%.png $(GUETZLI) --quality 90 "$<" "$@" diff --git a/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress.cfg b/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress.cfg index 4db4437..4b832c5 100644 --- a/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress.cfg +++ b/homepage/redesign2018/markdownExperiment/src/Makefiles/Makefiles.vidGal.d/Makefile.webmCompress.cfg @@ -7,6 +7,9 @@ DEFAULT_FFMPEG = ffmpeg #DEFAULT_FFMPEG = /c/proggis/media/editoren/ffmpeg-4.0.2-win64-static/bin/ffmpeg.exe GET_VIDEO_DURATION_JSON = /d/temp/cwsvJudo/homepage/redesign2018/markdownExperiment/src/galleryHelper/getVideoDurationJson.py +#GET_VIDEO_DURATION_JSON = ~/keeper/cwsvJudo/homepage/redesign2018/markdownExperiment/src/galleryHelper/getVideoDurationJson.py + +getTargetParameter = /d/temp/cwsvJudo/homepage/redesign2018/markdownExperiment/src/galleryHelper/getFfmpegFlags.py # Für eine schnelle Komprimierung libvpx, sonst vp9 @@ -41,11 +44,15 @@ jpegThumbs = $(addprefix videos/thumbnails/, $(addsuffix .jpg, $(basename $(n ffmpegVideoFilterVidstabDetect = vidstabdetect=shakiness=10:accuracy=15 # das input= fehlt absichtlich ffmpegVideoFilterVidstabTransform = vidstabtransform=optzoom=2:interpol=bicubic:smoothing=30 +# vidstab empfiehlt die Verwendung des unsharp-Filters bei vidstabtransform +ffmpegVideoFilterUnsharp = unsharp=5:5:0.8:3:3:0.4 #ffmpegVideoScaleFilter = scale=$(VID_CODEC_WIDTH):$(VID_CODEC_HEIGHT):sws_flags=lanczos, -ffmpegVideoScaleFilter = scale=if( gt(in_w, in_h), -2, $(VID_CODEC_HEIGHT) ):if( gt(in_w, in_h), $(VID_CODEC_HEIGHT), -2):sws_flags=lanczos, -ffmpegVideoFilterDeinterlace = yadif, -ffmpegVideoFilterDenoise = nlmeans, +#ffmpegVideoScaleFilter = scale=if\( gt\(in_w, in_h\), -2, $(VID_CODEC_HEIGHT) \):if\( gt\(in_w, in_h\), $(VID_CODEC_HEIGHT), -2\):sws_flags=lanczos +#ffmpegVideoScaleFilter = scale="if\(gt\(in_w\,in_h\)\,-2\,$(VID_CODEC_HEIGHT)\)":"if\(gt\(in_w\,in_h\)\,$(VID_CODEC_HEIGHT)\,-2\)":sws_flags=bicubic +ffmpegVideoScaleFilter = scale="if\(gt\(in_w\,in_h\)\,-2\,$(shell $(getTargetParameter) $< pixelSize)\)":"if\(gt\(in_w\,in_h\)\,$(shell $(getTargetParameter) $< pixelSize)\,-2\)":sws_flags=bicubic +ffmpegVideoFilterDeinterlace = yadif +ffmpegVideoFilterDenoise = nlmeans #ffmpegVideoFilterDenoise = hqdn3d, #ffmpegDisplayAspectRatio = 16:9 #ffmpegDisplayAspectRatio = 9:16 diff --git a/homepage/redesign2018/markdownExperiment/src/galleryHelper/getFfmpegFlags.py b/homepage/redesign2018/markdownExperiment/src/galleryHelper/getFfmpegFlags.py new file mode 100644 index 0000000..56d238a --- /dev/null +++ b/homepage/redesign2018/markdownExperiment/src/galleryHelper/getFfmpegFlags.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +# +# Command line use of 'ffprobe': +# +# ffprobe -loglevel quiet -print_format json \ +# -show_format -show_streams \ +# video-file-name.mp4 +# +# man ffprobe # for more information about ffprobe +# + +import subprocess as sp +import json +import sys +import argparse + + +def probe(vid_file_path): + ''' Give a json from ffprobe command line + + @vid_file_path : The absolute (full) path of the video file, string. + ''' + if type(vid_file_path) != str: + raise Exception('Give ffprobe a full file path of the video') + return + + command = ["ffprobe", + "-loglevel", "quiet", + "-print_format", "json", + "-show_format", + "-show_streams", + vid_file_path + ] + + pipe = sp.Popen(command, stdout=sp.PIPE, stderr=sp.STDOUT) + out, err = pipe.communicate() + return json.loads(out.decode('utf-8')) + +def duration(vid_file_path): + ''' Video's duration in seconds, return a float number + ''' + _json = probe(vid_file_path) + + if 'format' in _json: + if 'duration' in _json['format']: + return float(_json['format']['duration']) + + if 'streams' in _json: + # commonly stream 0 is the video + for s in _json['streams']: + if 'duration' in s: + return float(s['duration']) + + # if everything didn't happen, + # we got here because no single 'return' in the above happen. + raise Exception('I found no duration') + #return None + +def getPixelSize(bitrate): + if(bitrate >= 500): + return 480 + if(bitrate >= 250): + return 360 + return 240 + +if __name__ == "__main__": + argParser = argparse.ArgumentParser(description='Calculate Bitrate and Pixelsize (height) for a encoding a video with limited (byte-)size') + argParser.add_argument('inFile', help="file to be analysed") + argParser.add_argument('flagToGet', help="Zielparameter wählen", choices=['pixelSize', 'videoBitrate']) + argParser.add_argument('--audioBitrate', help="audio bitrate die abgezogen werden soll (in kbit/s)", default=0) + argParser.add_argument('--targetSize', help="dateigröße der zieldatei in MB", default=10) + argParser.add_argument('--overhead', help="prozentualer overhead in %", default=95) + argParser.add_argument('--maxVidBitrate', help="Videobitrate, bei der gedeckelt werden soll", default=750) + argv = argParser.parse_args() + + video_file_path = argv.inFile + + durationInSec = duration(video_file_path) + + videoBitrateInKbPerSec = argv.overhead/100 * (argv.targetSize * 1000 * 8)/durationInSec - argv.audioBitrate + videoBitrateInKbPerSec = int(min(argv.maxVidBitrate, videoBitrateInKbPerSec)) + + pixelSize = getPixelSize(videoBitrateInKbPerSec) + + if(argv.flagToGet == "pixelSize"): + print(pixelSize) + + if(argv.flagToGet == "videoBitrate"): + print(videoBitrateInKbPerSec) +