1#!/usr/local/bin/bash 2 3# force indendation settings 4# vim: ts=4 shiftwidth=4 expandtab 5 6######################################################################## 7######################################################################## 8######################################################################## 9 10# Copyright (C) 2017 Tomasz Wisniewski aka 11# DAGON <tomasz.wisni3wski@gmail.com> 12# 13# http://github.com/dagon666 14# http://pcarduino.blogspot.co.uk 15# 16# 17# This program is free software: you can redistribute it and/or modify 18# it under the terms of the GNU General Public License as published by 19# the Free Software Foundation, either version 3 of the License, or 20# (at your option) any later version. 21# 22# This program is distributed in the hope that it will be useful, 23# but WITHOUT ANY WARRANTY; without even the implied warranty of 24# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25# GNU General Public License for more details. 26# 27# You should have received a copy of the GNU General Public License 28# along with this program. If not, see <http://www.gnu.org/licenses/>. 29 30######################################################################## 31######################################################################## 32######################################################################## 33 34declare -r ___g_fsUnlink=0 35declare -r ___g_fsStat=1 36declare -r ___g_fsBase64=2 37declare -r ___g_fsMd5=3 38declare -r ___g_fsCp=4 39declare -r ___g_fs7z=5 40declare -r ___g_fsFps=6 41 42declare -a ___g_fsWrappers=( 'none' 'none' 'none' \ 43 'none' 'cp' 'none' 'none' ) 44 45___g_fsGarbageCollectorLog= 46 47######################################################################## 48 49# 50# @brief configure the stat tool 51# 52_fs_configureStat_GV() { 53 [ "${___g_fsWrappers[$___g_fsStat]}" = 'none' ] || return $G_RETNOACT 54 # verify stat tool 55 ___g_fsWrappers[$___g_fsStat]="stat -c%s " 56 57 if wrappers_isSystemDarwin || wrappers_isSystemFreeBSD; then 58 # stat may be installed through macports, check if 59 # there's a need to reconfigure it to BSD flavour 60 ${___g_fsWrappers[$___g_fsStat]} "$0" >/dev/null 2>&1 || 61 ___g_fsWrappers[$___g_fsStat]="stat -f%z " 62 fi 63} 64 65# 66# configure the base64 tool 67# 68_fs_configureBase64_GV() { 69 [ "${___g_fsWrappers[$___g_fsBase64]}" = 'none' ] || return $G_RETNOACT 70 ___g_fsWrappers[$___g_fsBase64]="base64 -d" 71 72 # verify base64 73 wrappers_isSystemDarwin && 74 ___g_fsWrappers[$___g_fsBase64]="base64 -D" 75 wrappers_isSystemFreeBSD && 76 ___g_fsWrappers[$___g_fsBase64]="base64 -d" 77} 78 79# 80# configure the md5 tool 81# 82_fs_configureMd5_GV() { 83 [ "${___g_fsWrappers[$___g_fsMd5]}" = 'none' ] || return $G_RETNOACT 84 85 # verify md5 tool 86 ___g_fsWrappers[$___g_fsMd5]="md5sum" 87 wrappers_isSystemDarwin && 88 ___g_fsWrappers[$___g_fsMd5]="md5" 89 wrappers_isSystemFreeBSD && 90 ___g_fsWrappers[$___g_fsMd5]="md5" 91} 92 93# 94# @brief configure the unlink tool 95# 96_fs_configureUnlink_GV() { 97 [ "${___g_fsWrappers[$___g_fsUnlink]}" = 'none' ] || return $G_RETNOACT 98 99 ___g_fsWrappers[$___g_fsUnlink]='rm -rf' 100 tools_isDetected "unlink" && 101 ___g_fsWrappers[$___g_fsUnlink]='unlink' 102} 103 104# 105# @brief verify presence of any of the 7z tools 106# 107_fs_configure7z_GV() { 108 [ "${___g_fsWrappers[$___g_fs7z]}" = 'none' ] || return $G_RETNOACT 109 local k='' 110 111 # use 7z or 7za only, 7zr doesn't support passwords 112 declare -a t7zs=( '7za' '7z' ) 113 114 for k in "${t7zs[@]}"; do 115 tools_isDetected "$k" && 116 ___g_fsWrappers[$___g_fs7z]="$k" && 117 break 118 done 119} 120 121# 122# @brief exit callback performing temporary files garbage collection 123# 124_fs_garbageCollectorCleaner() { 125 [ -z "$___g_fsGarbageCollectorLog" ] && return 126 127 logging_debug $LINENO $"usuwam pliki tymczasowe" 128 129 local entry= 130 while IFS='' read -r entry && [ -n "$entry" ]; do 131 [ -e "$entry" ] && { 132 logging_debug $LINENO $"usuwam" "[$entry]" 133 rm -rf "$entry" 134 } 135 done < "$___g_fsGarbageCollectorLog" 136 137 logging_debug $LINENO \ 138 $"usuwam dziennik plikow tymczasowych" "[$___g_fsGarbageCollectorLog]" 139 rm -rf "$___g_fsGarbageCollectorLog" 140} 141 142# 143# @brief garbage collector callback installer 144# 145_fs_configureGarbageCollector() { 146 [ -n "$___g_fsGarbageCollectorLog" ] && return 147 ___g_fsGarbageCollectorLog=$(mktemp -t napi.gclog.XXXXXXXX) 148 trap _fs_garbageCollectorCleaner EXIT 149} 150 151# 152# @brief verify configured fps tool 153# 154_fs_verifyFpsTool() { 155 # don't do anything if the tool has been already marked as unavailable 156 [ "${___g_fsWrappers[$___g_fsFps]}" = 'unavailable' ] && 157 return $G_RETUNAV 158 159 # verify selected fps tool 160 if [ "${___g_fsWrappers[$___g_fsFps]}" = 'none' ] || 161 ! tools_isInGroupAndDetected 'fps' \ 162 "${___g_fsWrappers[$___g_fsFps]}"; then 163 # choose first available as the default tool 164 local firstav='' 165 firstav=$(tools_getFirstAvailableFromGroup_SO "fps") 166 [ -z "$firstav" ] && return $G_RETPARAM 167 ___g_fsWrappers[$___g_fsFps]="$firstav" 168 fi 169} 170 171# 172# @brief detect fps of the video file 173# @param tool 174# @param filepath 175# 176_fs_getFpsWithTool() { 177 local fps=0 178 local tbr=0 179 local t="${1:-none}" 180 181 local tmp='' 182 declare -a atmp=() 183 184 # don't bother if there's no tool available or not specified 185 if [ -z "$t" ] || 186 [ "$t" = "none" ] || 187 [ "$t" = "unavailable" ] || 188 ! tools_isDetected "$t"; then 189 echo $fps 190 # shellcheck disable=SC2086 191 return $G_RETPARAM 192 fi 193 194 case "$t" in 195 'mplayer' | 'mplayer2' ) 196 fps=$($t -identify -vo null \ 197 -ao null \ 198 -frames 0 "$2" 2> /dev/null | \ 199 grep ID_VIDEO_FPS | \ 200 cut -d '=' -f 2) 201 ;; 202 203 'mediainfo' ) 204 fps=$($t --Output='Video;%FrameRate%' "$2") 205 ;; 206 207 'ffmpeg' ) 208 tmp=$($t -i "$2" 2>&1 | grep "Video:") 209 tbr=$(echo "$tmp" | \ 210 sed 's/, /\n/g' | \ 211 tr -d ')(' | \ 212 grep tbr | \ 213 cut -d ' ' -f 1) 214 fps=$(echo "$tmp" | \ 215 sed 's/, /\n/g' | \ 216 grep fps | \ 217 cut -d ' ' -f 1) 218 [ -z "$fps" ] && fps="$tbr" 219 ;; 220 221 'ffprobe' ) 222 tmp=$("$t" -v 0 \ 223 -select_streams v \ 224 -print_format csv \ 225 -show_entries \ 226 stream=avg_frame_rate,r_frame_rate -- "$2" | \ 227 tr ',' ' ') 228 atmp=( $tmp ) 229 230 local i=0 231 for i in 1 2; do 232 local a=$(echo "${atmp[$i]}" | cut -d '/' -f 1) 233 local b=$(echo "${atmp[$i]}" | cut -d '/' -f 2) 234 [ "${atmp[$i]}" != "0/0" ] && fps=$(wrappers_floatDiv "$a" "$b") 235 done 236 ;; 237 238 *) 239 ;; 240 esac 241 242 # just a precaution 243 echo "$fps" | cut -d ' ' -f 1 244} 245 246######################################################################## 247 248# 249# @brief configure the library 250# 251fs_configure_GV() { 252 _fs_configureStat_GV 253 _fs_configureBase64_GV 254 _fs_configureMd5_GV 255 _fs_configureUnlink_GV 256 _fs_configure7z_GV 257 _fs_configureGarbageCollector 258 _fs_verifyFpsTool 259} 260 261# 262# @brief stat wrapper 263# 264fs_stat_SO() { 265 ${___g_fsWrappers[$___g_fsStat]} "$@" 266} 267 268# 269# @brief base64 wrapper 270# 271fs_base64Decode_SO() { 272 ${___g_fsWrappers[$___g_fsBase64]} "$@" 273} 274 275# 276# @brief md5 wrapper 277# 278fs_md5_SO() { 279 ${___g_fsWrappers[$___g_fsMd5]} "$@" 280} 281 282# 283# @brief wrapper for copy function 284# 285fs_cp() { 286 ${___g_fsWrappers[$___g_fsCp]} "$@" 287} 288 289# 290# @brief set copy executable 291# 292fs_setCp_GV() { 293 ___g_fsWrappers[$___g_fsCp]="${1:-cp}" 294} 295 296# 297# @brief unlink wrapper 298# 299fs_unlink() { 300 ${___g_fsWrappers[$___g_fsUnlink]} "$@" 301} 302 303# 304# @brief 7z wrapper 305# 306fs_7z_SO() { 307 [ "${___g_fsWrappers[$___g_fs7z]}" != 'none' ] && 308 ${___g_fsWrappers[$___g_fs7z]} "$@" 309} 310 311# 312# @brief returns true if 7z is available 313# 314fs_is7zAvailable() { 315 [ "${___g_fsWrappers[$___g_fs7z]}" != 'none' ] 316} 317 318# 319# @brief adds a given file to be garbage collected at exit 320# 321fs_garbageCollect() { 322 [ -e "$1" ] && echo "$1" >> "$___g_fsGarbageCollectorLog" 323} 324 325# 326# @brief adds a given file to be garbage collected at exit 327# The file does not have to exist when being added 328# 329fs_garbageCollectUnexisting() { 330 echo "$1" >> "$___g_fsGarbageCollectorLog" 331} 332 333# 334# @brief create temporary directory 335# 336fs_mktempDir_SO() { 337 local dirPath=$(mktemp -d -t napi.XXXXXXXX) 338 fs_garbageCollect "${dirPath}/" 339 echo "${dirPath}/" 340} 341 342# 343# @brief create temporary file 344# 345fs_mktempFile_SO() { 346 local filePath=$(mktemp -t napi.XXXXXXXX) 347 fs_garbageCollect "${filePath}" 348 echo "${filePath}" 349} 350 351# 352# @brief: check if the given file is a supported video file 353# @param: video filename 354# 355fs_isVideoFile() { 356 local filename=$(basename "$1") 357 local extension=$(wrappers_getExt_SO "$filename" | wrappers_lcase_SO) 358 local formats=( 'avi' 'rmvb' 'mov' 'mp4' 'mpg' 'mkv' \ 359 'mpeg' 'wmv' '3gp' 'asf' 'divx' \ 360 'm4v' 'mpe' 'ogg' 'ogv' 'qt' ) 361 362 assoc_lookupKey_SO "$extension" "${formats[@]}" >/dev/null 363} 364 365# 366# @brief set fps tool 367# 368fs_setFpsTool_GV() { 369 ___g_fsWrappers[$___g_fsFps]="${1:-none}" 370 371 _fs_verifyFpsTool || 372 ___g_fsWrappers[$___g_fsFps]="unavailable" 373} 374 375# 376# @brief get fps of a media file 377# 378fs_getFps_SO() { 379 [ "${___g_fsWrappers[$___g_fsFps]}" = 'none' ] && 380 return "$G_RETUNAV" 381 _fs_getFpsWithTool "${___g_fsWrappers[$___g_fsFps]}" "$@" 382} 383 384# EOF 385