summaryrefslogtreecommitdiff
path: root/localvideowebencode
blob: d020a461580fd5b38a99e6d8b5227ab98cc10d9e (plain)
  1. #!/bin/sh
  2. # Origins:
  3. # http://diveintohtml5.org/video.html
  4. # http://camendesign.com/code/video_for_everybody
  5. # Possible flashplayers:
  6. # http://www.internetmarketingnotes.com/2010/07/free-embeddable-flash-video-flv-players-for-commercial-use/
  7. set -e
  8. PRG=$(basename "$0")
  9. showhelp() {
  10. cat <<EOF
  11. Usage: $PRG --size SIZE [--profile PROFILE] [--title TITLE] INPUTFILE
  12. Encode video file in multiple web-optimized formats, and provide sample
  13. html favoring open formats with optional non-JavaScript Flash fallback.
  14. -s, --size Output size in WIDTHxHEIGHT
  15. (mandatory)
  16. -p, --profile Quality profile (lo, hi, lowide, hiwide)
  17. (default: lo)
  18. -t, --title Title used in html fallback graphics
  19. (default: basename of input file)
  20. -h, --help This help text
  21. Examples:
  22. $PRG -s 320x200 -t "Funny guy" myvideo.dv
  23. More info: http://camendesign.com/code/video_for_everybody
  24. EOF
  25. }
  26. exit1() {
  27. response="${1:+Error: }${1:-Internal error!}"
  28. echo >&2 "$response"
  29. exit 1
  30. }
  31. # parse cmdline options
  32. TEMP="`getopt -s sh -o hs:p:t: -l help,size:,profile:,title: -n "$PRG" -- "$@"`" || exit1 "Internal getopt error."
  33. eval set -- "$TEMP"
  34. while true ; do
  35. case "$1" in
  36. -h|--help) showhelp; exit;;
  37. -s|--size) size="$2"; shift 2;;
  38. -p|--profile) profile="$2"; shift 2;;
  39. -t|--title) title="$2"; shift 2;;
  40. --) shift; break;;
  41. *) exit1 "Internal error resolving options.";;
  42. esac
  43. done
  44. if [ $# -eq 0 ]; then
  45. showhelp
  46. exit1 "Too few parameters!"
  47. fi
  48. if [ $# -gt 1 ]; then
  49. showhelp
  50. exit1 "Too many parameters!"
  51. fi
  52. # input filename (mandatory)
  53. infile="$1"; shift
  54. [ -e "$infile" ] || exit1 "Input file missing!"
  55. filebase=$(echo "$infile" | perl -pe 's/\.[^.]*//')
  56. # output size in WIDTHxHEIGHT (mandatory)
  57. # TODO: Make optional with input size as default
  58. # TODO: Make each half of size optional with default resolved from input aspect ratio
  59. [ -n "$size" ] || exit1 "Unknown output size!"
  60. width=$(echo "$size" | perl -pe 's/x[^x]*//')
  61. height=$(echo "$size" | perl -pe 's/[^x]*x//')
  62. heightplus=${height:+$(($height+4))}
  63. # fallback profile
  64. profile=${profile:-lo}
  65. case "$profile" in
  66. lo)
  67. bitrateKB=200
  68. bitrateB=204800
  69. aspect=4:3
  70. ;;
  71. lowide)
  72. bitrateKB=200
  73. bitrateB=204800
  74. aspect=16:9
  75. ;;
  76. hi)
  77. bitrateKB=400
  78. bitrateB=409600
  79. aspect=4:3
  80. ;;
  81. hiwide)
  82. bitrateKB=400
  83. bitrateB=409600
  84. aspect=16:9
  85. ;;
  86. esac
  87. # fallback graphics title
  88. title=${title:-$filebase}
  89. # TODO: Check and fail if all needed tools are not available
  90. ## Theora/Vorbis/Ogg
  91. ffmpeg2theora --videobitrate "$bitrateKB" --max_size "$size" --aspect "$aspect" --output "$filebase.ogv" "$infile"
  92. ## H.264/AAC/MP4
  93. HandBrakeCLI --preset "iPhone & iPod Touch" --vb "$bitrateKB" ${width:+--maxWidth "$width"} ${height:+--maxHeight "$height"} --two-pass --turbo --optimize --input "$infile" --output "$filebase.mp4"
  94. ## VP8/Vorbis/WebM
  95. ! ffmpeg -codecs | grep -iw vp8 || webm=yes
  96. # FIXME: check and fail if logfiles exist already
  97. [ -z "$webm" ] || ffmpeg -pass 1 -passlogfile "$infile" -threads 16 -keyint_min 0 -g 250 -skip_threshold 0 -qmin 1 -qmax 51 -i "$infile" -vcodec libvpx -b "$bitrateB" -s "$size" -aspect "$aspect" -an -f webm -y NUL
  98. [ -z "$webm" ] || ffmpeg -pass 2 -passlogfile "$infile" -threads 16 -keyint_min 0 -g 250 -skip_threshold 0 -qmin 1 -qmax 51 -i "$infile" -vcodec libvpx -b "$bitrateB" -s "$size" -aspect "$aspect" -acodec libvorbis -ac 2 -y "$filebase.webm"
  99. rm "$infile"-*.log
  100. ## JPEG preview
  101. ffmpegthumbnailer -s0 -i "$filebase.ogv" -o "$filebase.jpg"
  102. # TODO: resolve flash player to use
  103. [ -z "$flashplayer" ] || flash=yes
  104. cat >"$filebase.html" <<EOF
  105. <!-- Video for Everybody, Kroc Camen of Camen Design -->
  106. <video width="$width" height="$height" preload controls>
  107. <source src="$filebase.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
  108. <source src="$filebase.ogv" type='video/ogg; codecs="theora, vorbis"' />
  109. ${webm:+<source src="$filebase.webm" type='video/webm; codecs="vp8, vorbis"' />
  110. }${flash:+<object width="$width" height="$heightplus" type="application/x-shockwave-flash" data="$flashplayer.swf">
  111. <param name="movie" value="$flashplayer.swf" />
  112. <param name="flashvars" value="image=$filebase.jpg&amp;file=$filebase.mp4" />
  113. }<img src="$filebase.jpg" width="$width" height="$height" alt="$title"
  114. title="No video playback capabilities, please download the video below" />
  115. ${flash:+</object>
  116. }</video>
  117. <p><strong>Download Video:</strong>
  118. open format <a href="$filebase.ogv">Ogg</a>,
  119. ${webm:+open format <a href="$filebase.webm">WebM</a>,}
  120. closed Format <a href="$filebase.mp4">MP4</a>.
  121. </p>
  122. EOF