amagi_transcode 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +48 -0
  4. data/README.md +140 -0
  5. data/amagi_transcode.gemspec +26 -0
  6. data/bin/console +14 -0
  7. data/bin/mediainfo +0 -0
  8. data/lib/.DS_Store +0 -0
  9. data/lib/xmorph/.DS_Store +0 -0
  10. data/lib/xmorph/base.rb +261 -0
  11. data/lib/xmorph/customers/cbn/cbn/transcode.rb +51 -0
  12. data/lib/xmorph/customers/cinedigm/Cinedigm/transcode.rb +107 -0
  13. data/lib/xmorph/customers/curiosity/curiosity/transcode.rb +36 -0
  14. data/lib/xmorph/customers/dogtv/dogtv/transcode.rb +44 -0
  15. data/lib/xmorph/customers/gusto/gusto/transcode.rb +75 -0
  16. data/lib/xmorph/customers/hkitv/hkitv/transcode.rb +44 -0
  17. data/lib/xmorph/customers/hungama/Hungama/transcode.rb +36 -0
  18. data/lib/xmorph/customers/kalpnik/kalpnik/transcode.rb +40 -0
  19. data/lib/xmorph/customers/lightning/LIG/transcode.rb +36 -0
  20. data/lib/xmorph/customers/peopletv/peopletv/transcode.rb +36 -0
  21. data/lib/xmorph/customers/rewind/rewind/transcode.rb +50 -0
  22. data/lib/xmorph/customers/rooster-teeth/roosterteeth/transcode.rb +36 -0
  23. data/lib/xmorph/customers/sabatv/sabatv/transcode.rb +37 -0
  24. data/lib/xmorph/customers/scripps-cp/scpbu/transcode.rb +36 -0
  25. data/lib/xmorph/customers/shoutfactory/shoutfactory/transcode.rb +68 -0
  26. data/lib/xmorph/customers/tastemade/tastemade/transcode.rb +36 -0
  27. data/lib/xmorph/customers/tern-cp/TCP/transcode.rb +36 -0
  28. data/lib/xmorph/customers/turner-nordic/TurnerNordic/transcode.rb +117 -0
  29. data/lib/xmorph/customers/tyt/TYT/transcode.rb +52 -0
  30. data/lib/xmorph/customers/zsports/asn/transcode.rb +50 -0
  31. data/lib/xmorph/error.rb +3 -0
  32. data/lib/xmorph/util.rb +43 -0
  33. data/lib/xmorph/version.rb +3 -0
  34. data/lib/xmorph.rb +6 -0
  35. metadata +133 -0
@@ -0,0 +1,117 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ PRO_4_3_STEREO = "4_3_STEREO"
4
+ PRO_4_3_MORE_CH_4 = "4_3_MORE_CH_4"
5
+ PRO_4_3_MORE_CH_8 = "4_3_MORE_CH_8"
6
+ PRO_4_3_2_TRACKS = "4_3_2_TRACKS"
7
+ PRO_4_3_4_TRACKS = "4_3_4_TRACKS"
8
+ PRO_4_3_6_TRACKS = "4_3_6_TRACKS"
9
+ PRO_4_3_8_TRACKS = "4_3_8_TRACKS"
10
+
11
+ PRO_16_9_STEREO = "16_9_STEREO"
12
+ PRO_16_9_MORE_CH_4 = "16_9_MORE_CH_4"
13
+ PRO_16_9_MORE_CH_8 = "16_9_MORE_CH_8"
14
+ PRO_16_9_2_TRACKS = "16_9_2_TRACKS"
15
+ PRO_16_9_4_TRACKS = "16_9_4_TRACKS"
16
+ PRO_16_9_6_TRACKS = "16_9_6_TRACKS"
17
+ PRO_16_9_8_TRACKS = "16_9_8_TRACKS"
18
+
19
+ PRO_1080_STEREO = "1080_STEREO"
20
+ PRO_1080_MORE_CH_4 = "1080_MORE_CH_4"
21
+ PRO_1080_MORE_CH_8 = "1080_MORE_CH_8"
22
+ PRO_1080_2_TRACKS = "1080_2_TRACKS"
23
+ PRO_1080_4_TRACKS = "1080_4_TRACKS"
24
+ PRO_1080_6_TRACKS = "1080_6_TRACKS"
25
+ PRO_1080_8_TRACKS = "1080_8_TRACKS"
26
+
27
+
28
+ def set_profiles
29
+ self.profiles = {
30
+ PRO_4_3_STEREO => "ffmpeg -y -i %{IN} -map 0:v -map 0:a -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -bf 2 -profile:v high -aspect 4:3 -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 -streamid 5:2072 -streamid 6:2073 -streamid 7:2074 -streamid 8:2075 %{OUT} 2>&1",
31
+ PRO_4_3_MORE_CH_4 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b]\" -map \"[a]\" -map \"[b]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 4:3 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 %{OUT} 2>&1",
32
+ PRO_4_3_MORE_CH_8 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b];[0]pan=stereo|c0=c4|c1=c5[c];[0]pan=stereo|c0=c6|c1=c7[d]\" -map \"[a]\" -map \"[b]\" -map \"[c]\" -map \"[d]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 4:3 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 -streamid 5:2072 -streamid 6:2073 -streamid 7:2074 -streamid 8:2075 %{OUT} 2>&1",
33
+ PRO_4_3_2_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -aspect 4:3 -g 13 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
34
+ PRO_4_3_4_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -aspect 4:3 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
35
+ PRO_4_3_6_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 4:3 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
36
+ PRO_4_3_8_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -filter_complex \"[0:a:6][0:a:7] amerge=inputs=2[audio4]\" -map [audio4] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 4:3 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
37
+
38
+ PRO_16_9_STEREO => "ffmpeg -y -i %{IN} -map 0:v -map 0:a -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -bf 2 -profile:v high -aspect 16:9 -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 -streamid 5:2072 -streamid 6:2073 -streamid 7:2074 -streamid 8:2075 %{OUT} 2>&1",
39
+ PRO_16_9_MORE_CH_4 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b]\" -map \"[a]\" -map \"[b]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 %{OUT} 2>&1",
40
+ PRO_16_9_MORE_CH_8 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b];[0]pan=stereo|c0=c4|c1=c5[c];[0]pan=stereo|c0=c6|c1=c7[d]\" -map \"[a]\" -map \"[b]\" -map \"[c]\" -map \"[d]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 -streamid 5:2072 -streamid 6:2073 -streamid 7:2074 -streamid 8:2075 %{OUT} 2>&1",
41
+ PRO_16_9_2_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
42
+ PRO_16_9_4_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
43
+ PRO_16_9_6_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
44
+ PRO_16_9_8_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -filter_complex \"[0:a:6][0:a:7] amerge=inputs=2[audio4]\" -map [audio4] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -filter:v \"crop=720:576:0:32\" -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
45
+
46
+ PRO_1080_STEREO => "ffmpeg -y -i %{IN} -map 0:v -map 0:a -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
47
+ PRO_1080_MORE_CH_4 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b]\" -map \"[a]\" -map \"[b]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 %{OUT} 2>&1",
48
+ PRO_1080_MORE_CH_8 => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0]pan=stereo|c0=c0|c1=c1[a];[0]pan=stereo|c0=c2|c1=c3[b];[0]pan=stereo|c0=c4|c1=c5[c];[0]pan=stereo|c0=c6|c1=c7[d]\" -map \"[a]\" -map \"[b]\" -map \"[c]\" -map \"[d]\" -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 -streamid 5:2072 -streamid 6:2073 -streamid 7:2074 -streamid 8:2075 %{OUT} 2>&1",
49
+ PRO_1080_2_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
50
+ PRO_1080_4_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
51
+ PRO_1080_6_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
52
+ PRO_1080_8_TRACKS => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0][0:a:1] amerge=inputs=2[audio1]\" -map [audio1] -filter_complex \"[0:a:2][0:a:3] amerge=inputs=2[audio2]\" -map [audio2] -filter_complex \"[0:a:4][0:a:5] amerge=inputs=2[audio3]\" -map [audio3] -filter_complex \"[0:a:6][0:a:7] amerge=inputs=2[audio4]\" -map [audio4] -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -pix_fmt yuv420p -flags +ilme+ildct -x264opts tff=1 -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -streamid 2:2069 -streamid 3:2070 -streamid 4:2071 %{OUT} 2>&1",
53
+ }
54
+ end
55
+
56
+ def video_checks
57
+ {
58
+ ALLOWED_ASPECT_RATIO => ["16:9", "4:3"],
59
+ ALLOWED_HEIGHT => [576, 608, 1080],
60
+ ALLOWED_WIDTH => [720, 1920],
61
+ ALLOWED_FRAME_RATE => IGNORE,
62
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
63
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
64
+ }
65
+ end
66
+
67
+ def audio_checks
68
+ {
69
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
70
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 2, 3, 4, 5, 8],
71
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm", "dolby e"],
72
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
73
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2, 4, 6, 8],
74
+ }
75
+ end
76
+
77
+ #profiles are classified based on aspect ratio, height and number of audio channels
78
+ #1. height is 1080 and audio tracks could be (1 track with stereo), (2, 4, 6, 8 tracks and all mono), (1 track with 4, 8 channels)
79
+ #2. line 1 applies with aspect ration as 4:3 and 16:9
80
+ def set_profile_name
81
+ self.profile_name = nil
82
+ mediainfo = self.mediainfo_output
83
+ video_info = mediainfo["Video"]
84
+ aspect_ratio = video_info["Display_aspect_ratio"]
85
+ height = (video_info["Original_height"] || video_info["Height"]).split("pixels")[0].gsub(/ /,"")
86
+
87
+ height = aspect_ratio.gsub(":","_") if height != "1080"
88
+
89
+ stereo = false
90
+ audio_tracks = mediainfo["Audio"]
91
+ audio_tracks.each do |audio|
92
+ stereo = true if audio["Channel_s_"] =~ /2/
93
+ end
94
+ more_than_two_chans = audio_tracks.size == 1 && (audio_tracks[0]["Channel_s__Original"]||audio_tracks[0]["Channel_s_"]).match(/(4|8)/)
95
+ ret = stereo ? height + "_stereo" : height + "_" + audio_tracks.size.to_s + "_tracks"
96
+ profile_name = more_than_two_chans ? height + "_more_ch_" + (audio_tracks[0]["Channel_s__Original"]||audio_tracks[0]["Channel_s_"]).match(/(4|8)/).to_s : ret
97
+
98
+ self.profile_name = self.class.const_get(("pro_" + profile_name).upcase) rescue nil
99
+ unless self.profiles.keys.include? self.profile_name
100
+ errors = []
101
+ channels = []
102
+ audio_tracks.each {|info| channels << (info["Channel_s__Original"] || info["Channel_s_"]).split("channels")[0].strip}
103
+ if audio_tracks.size == 1 and !((channels-["2","4","8"]).empty?)
104
+ errors << "Number of channels allowed if there's only 1 audio track is 2,4,8. But media has #{channels.join} channels"
105
+ end
106
+ if audio_tracks.size != 1 and !([2,4,6,8].include? audio_tracks.size) and !stereo
107
+ #todo think of better error msg
108
+ errors << "If the number of audio tracks is odd. One of the track must be stereo"
109
+ end
110
+ self.error = errors.join(" ; ") unless errors.empty?
111
+ return false
112
+ end
113
+ XMorph::Base.logger.debug("XMorph#set_profile_name#TurnerNordic: using profile #{self.profile_name}") unless self.profile_name.nil?
114
+ return true
115
+ end
116
+
117
+ end
@@ -0,0 +1,52 @@
1
+ class Transcode < XMorph::Base
2
+ CINEDIGM_CONTENT = "cinedigm_content"
3
+ DEFAULT = "default"
4
+ def set_profiles
5
+ self.profiles = {
6
+ CINEDIGM_CONTENT => "ffmpeg -y -i %{IN} -map 0:v:0 -map 0:a:0 -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -vf 'fps=fps=29.97,scale=1920:1080' -pix_fmt yuv420p -g 13 -bf 2 -profile:v high -vb 30000k -minrate:v 30000k -maxrate:v 30000k -bufsize:v 60000k -muxrate 31000k -x264opts nal-hrd=cbr -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
7
+ DEFAULT => "ffmpeg -y -i %{IN} -vcodec copy -vbsf h264_mp4toannexb -acodec copy -map 0:v -streamid 0:2064 -map 0:a -streamid 1:2068 -metadata:s:a:0 language=ENG %{OUT} 2>&1",
8
+ }
9
+ end
10
+
11
+ def video_checks
12
+ {
13
+ ALLOWED_ASPECT_RATIO => ["16:9"],
14
+ ALLOWED_HEIGHT => [1080],
15
+ ALLOWED_WIDTH => [1920],
16
+ ALLOWED_FRAME_RATE => IGNORE,
17
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
18
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
19
+ }
20
+ end
21
+
22
+ def audio_checks
23
+ {
24
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
25
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
26
+ ALLOWED_AUDIO_CODECS => ["aac", "mpeg audio"],
27
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
28
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
29
+ }
30
+ end
31
+
32
+ #profiles are classified based on fps and bit rate.
33
+ def set_profile_name
34
+ self.profile_name = nil
35
+ self.error = nil
36
+ mediainfo = self.mediainfo_output
37
+ video_info = mediainfo["Video"]
38
+ fps = video_info["Frame_rate"]
39
+ bit_rate = video_info["Bit_rate"] || video_info["Nominal_bit_rate"]
40
+
41
+ fps = video_info["Frame_rate"].match("29.97")
42
+ bit_rate = bit_rate.split(" ")[0].to_f
43
+ if !fps || bit_rate < 30;
44
+ self.profile_name = CINEDIGM_CONTENT
45
+ else
46
+ self.profile_name = DEFAULT
47
+ end
48
+ XMorph::Base.logger.debug("XMorph#set_profile_name#tyt: using profile #{self.profile_name}") unless self.profile_name.nil?
49
+ return true
50
+ end
51
+
52
+ end
@@ -0,0 +1,50 @@
1
+ class Transcode < XMorph::Base
2
+ MONO = "mono"
3
+ STEREO = "stereo"
4
+ def set_profiles
5
+ self.profiles = {
6
+ MONO => "ffmpeg -y -i %{IN} -map 0:v -filter_complex \"[0:a:0]aformat=sample_fmts=fltp:sample_rates=48000:channel_layouts=mono[a1]; [0:a:1]aformat=sample_fmts=fltp:sample_rates=48000:channel_layouts=mono[a2]; [a1][a2]amerge[aout0]\" -map \"[aout0]\" -acodec libfdk_aac -vf \"fps=fps=25,scale=1920:1080\" -vcodec libx264 -pix_fmt yuv420p -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -flags +ilme+ildct -top 1 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 -ac 2 %{OUT} 2>&1",
7
+ STEREO => "ffmpeg -y -i %{IN} -map 0:v -map 0:a -acodec libfdk_aac -vf \"fps=fps=25,scale=1920:1080\" -vcodec libx264 -pix_fmt yuv420p -x264opts nal-hrd=cbr -g 13 -aspect 16:9 -bf 2 -flags +ilme+ildct -top 1 -profile:v high -b:v 12M -minrate:v 12M -maxrate:v 12M -muxrate 14M -bufsize:v 25M -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 -ac 2 %{OUT} 2>&1",
8
+ }
9
+ end
10
+
11
+ def video_checks
12
+ {
13
+ ALLOWED_ASPECT_RATIO => ["16:9"],
14
+ ALLOWED_HEIGHT => [720, 1080],
15
+ ALLOWED_WIDTH => [1280, 1920],
16
+ ALLOWED_FRAME_RATE => IGNORE,
17
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
18
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
19
+ }
20
+ end
21
+
22
+ def audio_checks
23
+ {
24
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
25
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 2, 4, 6, 8, 16],
26
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm", ".mp2"],
27
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
28
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2, 4],
29
+ }
30
+ end
31
+
32
+ #profiles are classified based on number channels in audio tracks.
33
+ def set_profile_name
34
+ self.profile_name = nil
35
+ mediainfo = self.mediainfo_output
36
+ mono = "true"
37
+ audio_tracks = mediainfo["Audio"]
38
+ audio_tracks.each_with_index do |audio, index|
39
+ if audio["Channel_s_"] =~ /2/
40
+ mono = "false"
41
+ elsif audio["Channel_s_"] =~ /1/
42
+ mono = "true"
43
+ end
44
+ end
45
+ self.profile_name = (mono == "true")? MONO : STEREO
46
+ XMorph::Base.logger.debug("XMorph#set_profile_name#TYT: using profile #{self.profile_name}") unless self.profile_name.nil?
47
+ return true
48
+ end
49
+
50
+ end
@@ -0,0 +1,3 @@
1
+ # Used for all execptions thrown from Transcoder
2
+ class TranscoderError < StandardError
3
+ end
@@ -0,0 +1,43 @@
1
+ module XMorph
2
+ require 'active_support'
3
+ class Util
4
+ def self.mediainfo_xml_to_hash(response)
5
+ meta = {
6
+ "Audio" => []
7
+ }
8
+ begin
9
+ response_json = Hash.from_xml(response)
10
+ response_json["Mediainfo"]["File"]["track"].each do |track|
11
+ type = track['type']
12
+ track = track.except("type")
13
+ track['Encoding_settings'] = Rack::Utils.parse_nested_query(track['Encoding_settings'].split("/").map {|pair| pair.strip }.join("&")) unless track['Encoding_settings'].nil?
14
+ (type == "Audio") ? meta["Audio"] << track : meta[type] = track
15
+ if type == "Video"
16
+ if track["Display_aspect_ratio"].present?
17
+ track["Display_aspect_ratio"] = track["Display_aspect_ratio"] if track["Display_aspect_ratio"].include? (":")
18
+ end
19
+ if track["Original_display_aspect_ratio"].present?
20
+ track["Display_aspect_ratio"] = track["Original_display_aspect_ratio"] if track["Original_display_aspect_ratio"].include? (":")
21
+ end
22
+ end
23
+ end
24
+ meta['audio_tracks'] = meta['Audio'].count.to_s
25
+ rescue => ex
26
+ puts ex
27
+ return false, {"error" => "Failed to load mediainfo"}
28
+ end
29
+ return true, meta
30
+ end
31
+
32
+ def self.run_cmd_with_response(cmd)
33
+ raw_response = `#{cmd}`
34
+ successful = true
35
+ exit_status = $?.exitstatus
36
+ if exit_status != 0
37
+ successful = false
38
+ end
39
+ return successful, raw_response
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module XMorph
2
+ VERSION = "0.1.14"
3
+ end
data/lib/xmorph.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative 'xmorph/version'
2
+ require_relative 'xmorph/base'
3
+ require_relative 'xmorph/error'
4
+ require_relative 'xmorph/util'
5
+ require 'active_support/all'
6
+ require 'active_support/inflector'
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amagi_transcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.14
5
+ platform: ruby
6
+ authors:
7
+ - tejaswini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.8.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Morphs things from one kind to another. Transcodes, in local speak, for
70
+ example.
71
+ email:
72
+ - tejaswini@amagi.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - README.md
80
+ - amagi_transcode.gemspec
81
+ - bin/console
82
+ - bin/mediainfo
83
+ - lib/.DS_Store
84
+ - lib/xmorph.rb
85
+ - lib/xmorph/.DS_Store
86
+ - lib/xmorph/base.rb
87
+ - lib/xmorph/customers/cbn/cbn/transcode.rb
88
+ - lib/xmorph/customers/cinedigm/Cinedigm/transcode.rb
89
+ - lib/xmorph/customers/curiosity/curiosity/transcode.rb
90
+ - lib/xmorph/customers/dogtv/dogtv/transcode.rb
91
+ - lib/xmorph/customers/gusto/gusto/transcode.rb
92
+ - lib/xmorph/customers/hkitv/hkitv/transcode.rb
93
+ - lib/xmorph/customers/hungama/Hungama/transcode.rb
94
+ - lib/xmorph/customers/kalpnik/kalpnik/transcode.rb
95
+ - lib/xmorph/customers/lightning/LIG/transcode.rb
96
+ - lib/xmorph/customers/peopletv/peopletv/transcode.rb
97
+ - lib/xmorph/customers/rewind/rewind/transcode.rb
98
+ - lib/xmorph/customers/rooster-teeth/roosterteeth/transcode.rb
99
+ - lib/xmorph/customers/sabatv/sabatv/transcode.rb
100
+ - lib/xmorph/customers/scripps-cp/scpbu/transcode.rb
101
+ - lib/xmorph/customers/shoutfactory/shoutfactory/transcode.rb
102
+ - lib/xmorph/customers/tastemade/tastemade/transcode.rb
103
+ - lib/xmorph/customers/tern-cp/TCP/transcode.rb
104
+ - lib/xmorph/customers/turner-nordic/TurnerNordic/transcode.rb
105
+ - lib/xmorph/customers/tyt/TYT/transcode.rb
106
+ - lib/xmorph/customers/zsports/asn/transcode.rb
107
+ - lib/xmorph/error.rb
108
+ - lib/xmorph/util.rb
109
+ - lib/xmorph/version.rb
110
+ homepage: https://github.com/amagimedia/xmorph
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubygems_version: 3.4.10
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Morphs things from one kind to another.
133
+ test_files: []