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,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "ffmpeg -y -i %{IN} -vf \"fps=29.970000,scale=1920x1080\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -vb 18000000 -minrate:v 18000000 -maxrate:v 18000000 -bufsize:v 36000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 20011200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1"
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080, 2160],
13
+ ALLOWED_WIDTH => [1920, 3840],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
24
+ ALLOWED_AUDIO_CODECS => ["pcm", "aac"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#curiosity: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ PROGRESSIVE = "progressive"
4
+ INTERLACED = "interlaced"
5
+ def set_profiles
6
+ self.profiles = {
7
+ PROGRESSIVE => "ffmpeg -y -i %{IN} -map 0:v -map 0:a:0 -map 0:a:0 -c:a:0 libfdk_aac -profile:a aac_low -ac 2 -ab 192k -c:a:1 ac3 -ac 2 -ab 320k -c:v libx264 -vf \"fps=fps=29.97,scale=1920:1080\" -pix_fmt yuv420p -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 -vsync 1 -async 1 %{OUT} 2>&1",
8
+ INTERLACED => "ffmpeg -y -i %{IN} -map 0:v -map 0:a:0 -map 0:a:0 -c:a:0 libfdk_aac -profile:a aac_low -ac 2 -ab 192k -c:a:1 ac3 -ac 2 -ab 320k -c:v libx264 -vf \"fps=fps=29.97,scale=1920:1080\" -pix_fmt yuv420p -flags +ilme+ildct -top 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 -vsync 1 -async 1 %{OUT} 2>&1"
9
+ }
10
+ end
11
+
12
+ def video_checks
13
+ {
14
+ ALLOWED_ASPECT_RATIO => ["16:9"],
15
+ ALLOWED_HEIGHT => [1080],
16
+ ALLOWED_WIDTH => [1920],
17
+ ALLOWED_FRAME_RATE => IGNORE,
18
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
19
+ ALLOWED_SCAN_TYPE => ["progressive", "interlaced", "interlaced_mbaff", "interlaced_tff", "interlaced_bff"], #all downcased
20
+ }
21
+ end
22
+
23
+ def audio_checks
24
+ {
25
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
26
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 2],
27
+ ALLOWED_AUDIO_CODECS => ["ac-3", "aac"],
28
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
29
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
30
+ }
31
+ end
32
+
33
+ # Classification is based on scan type
34
+ # Video of type progressive and interlaced are scaled to 1920x1080
35
+ def set_profile_name
36
+ self.profile_name = nil
37
+ self.error = nil
38
+ mediainfo = self.mediainfo_output
39
+ scan_type = mediainfo["Video"]["Scan_type"]
40
+ self.profile_name = (scan_type.downcase == "progressive")? PROGRESSIVE : INTERLACED
41
+ XMorph::Base.logger.debug("XMorph#set_profile_name#dogtv: using profile #{self.profile_name}") unless self.profile_name.nil?
42
+ return true
43
+ end
44
+ end
@@ -0,0 +1,75 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ PRO_1080_16_TRACKS = "1080_16"
4
+ PRO_1080_14_TRACKS = "1080_14"
5
+ PRO_1080_8_TRACKS = "1080_8"
6
+ PRO_1080_2_TRACKS = "1080_2"
7
+ PRO_1080_STEREO = "1080_stereo"
8
+ PRO_720_STEREO = "720_stereo"
9
+
10
+ def set_profiles
11
+ self.profiles = {
12
+ PRO_1080_16_TRACKS => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -filter_complex \"[0:a:8][0:a:9]amerge=inputs=2[aout0]\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map \"[aout0]\" -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
13
+ PRO_1080_14_TRACKS => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -filter_complex \"[0:a:6][0:a:7]amerge=inputs=2[aout0]\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map \"[aout0]\" -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
14
+ PRO_1080_8_TRACKS => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -filter_complex \"[0:a:6][0:a:7]amerge=inputs=2[aout0]\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map \"[aout0]\" -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
15
+ PRO_1080_2_TRACKS => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -filter_complex \"[0:a:1][0:a:2]amerge=inputs=2[aout0]\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map \"[aout0]\" -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
16
+ PRO_1080_STEREO => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1",
17
+ PRO_720_STEREO => "ffmpeg -y -i %{IN} -vf \"fps=25.000000,scale=1920x1080\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 10000000 -minrate:v 10000000 -maxrate:v 10000000 -bufsize:v 20000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 11211200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1",
18
+ }
19
+ end
20
+
21
+ def video_checks
22
+ {
23
+ ALLOWED_ASPECT_RATIO => ["4:3", "16:9"],
24
+ ALLOWED_HEIGHT => [720, 1080],
25
+ ALLOWED_WIDTH => [1280, 1920],
26
+ ALLOWED_FRAME_RATE => IGNORE,
27
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
28
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
29
+ }
30
+ end
31
+
32
+ def audio_checks
33
+ {
34
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
35
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 4, 8, 14, 16],
36
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm"],
37
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
38
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
39
+ }
40
+ end
41
+
42
+ #profiles are classified based on height and number of audio tracks
43
+ #1. height can either be 720 or 1080
44
+ #2. if height is 720, one of the audio track must be stereo
45
+ #3. if height is 1080, one of the audio track can be stereo, or it can have, 2,8,14,16 audio tracks
46
+ def set_profile_name
47
+ self.profile_name = nil
48
+ self.error = nil
49
+
50
+ mediainfo = self.mediainfo_output
51
+ height = (mediainfo["Video"]["Original_height"] || mediainfo["Video"]["Height"]).split("pixels")[0].gsub(/ /,"")
52
+
53
+ stereo = false
54
+ audio_tracks = mediainfo["Audio"]
55
+ audio_tracks.each do |track|
56
+ stereo = true if track["Channel_s_"] =~ /2/
57
+ end
58
+ profile_name = (stereo ? height + "_stereo" : height + "_" + audio_tracks.size.to_s + "_tracks")
59
+ self.profile_name = self.class.const_get(("pro_" + profile_name).upcase) rescue nil
60
+ unless self.profiles.keys.include? self.profile_name
61
+ if height == "720" and !stereo
62
+ self.error = "Media with height 720 is supported only if it has a stereo track."
63
+ end
64
+ if height == "1080" and !([16,14,8,2].include? audio_tracks.size)
65
+ self.error = "Media with height 1080 is supported only with 16, 14, 8 or 2 audio tracks. But media has #{audio_tracks.size} tracks and is not stereo."
66
+ end
67
+ return false
68
+ end
69
+ unless self.profile_name.nil?
70
+ XMorph::Base.logger.debug("XMorph#set_profile_name#gusto: using profile #{self.profile_name}")
71
+ end
72
+ return true
73
+ end
74
+
75
+ end
@@ -0,0 +1,44 @@
1
+ class Transcode < XMorph::Base
2
+ ADD_AUDIO = "add_audio"
3
+ DEFAULT = "default"
4
+ def set_profiles
5
+ self.profiles = {
6
+ ADD_AUDIO => "ffmpeg -y -i %{IN} -f lavfi -i anullsrc -shortest -map 0:v:0 -map 1:a:0 -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -vf \"fps=fps=25,scale=720:576\" -pix_fmt yuv420p -g 13 -bf 2 -profile:v high -vb 8000000 -minrate:v 8000k -maxrate:v 8000k -bufsize:v 16000k -muxrate 9000k -x264opts nal-hrd=cbr -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
7
+ DEFAULT => "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=25,scale=720:576' -pix_fmt yuv420p -g 13 -bf 2 -profile:v high -vb 8000000 -minrate:v 8000k -maxrate:v 8000k -bufsize:v 16000k -muxrate 9000k -x264opts nal-hrd=cbr -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1"
8
+ }
9
+ end
10
+
11
+ def video_checks
12
+ {
13
+ ALLOWED_ASPECT_RATIO => ["16:9", "5:4"],
14
+ ALLOWED_HEIGHT => [720, 1080, 576],
15
+ ALLOWED_WIDTH => [1280, 1920, 720],
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 => IGNORE,
25
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [0, 1],
26
+ ALLOWED_AUDIO_CODECS => ["aac"],
27
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
28
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
29
+ }
30
+ end
31
+
32
+ # Classification is based on presence of audio track
33
+ # Audio track is added for Videos with no audio track
34
+ def set_profile_name
35
+ self.profile_name = nil
36
+ self.error = nil
37
+
38
+ mediainfo = self.mediainfo_output
39
+ audio_tracks = mediainfo["Audio"]
40
+ self.profile_name = (audio_tracks.empty?) ? ADD_AUDIO : DEFAULT
41
+ XMorph::Base.logger.debug("XMorph#set_profile_name#hkitv: using profile #{self.profile_name}") unless self.profile_name.nil?
42
+ return true
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "ffmpeg -y -i %{IN} -map 0:v -map 0:a:0 -acodec libfdk_aac -profile:a aac_low -ac 2 -ar 48000 -ab 192k -vcodec libx264 -vf \"fps=fps=25\" -vf \"scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2\" -pix_fmt yuv420p -flags +ilme+ildct -top 1 -g 13 -bf 2 -profile:v high -level 4.1 -vb 15000000 -minrate:v 15000000 -maxrate:v 15000000 -muxrate 16000000 -bufsize:v 30000000 -x264opts nal-hrd=cbr -refs 6 -keyint_min 1 -aspect 16:9 -deblock -1:-1 -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => IGNORE,
12
+ ALLOWED_HEIGHT => IGNORE,
13
+ ALLOWED_WIDTH => IGNORE,
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
24
+ ALLOWED_AUDIO_CODECS => ["aac"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#hungama: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ SCALE_TO_720p = "720"
4
+
5
+ def set_profiles
6
+ self.profiles = {
7
+ SCALE_TO_720p => "ffmpeg -y -i %{IN} -vf \"fps=fps=29.970000,scale=1280x720\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -vb 8000000 -minrate:v 8000000 -maxrate:v 8000000 -bufsize:v 24000000 -ar 48000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 8600000 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT}",
8
+ }
9
+ end
10
+
11
+ def video_checks
12
+ {
13
+ ALLOWED_ASPECT_RATIO => ["16:9"],
14
+ ALLOWED_HEIGHT => [720],
15
+ ALLOWED_WIDTH => [1280],
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"],
27
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
28
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
29
+ }
30
+ end
31
+
32
+ # Classification is based on Height
33
+ # Videos with height greater than 720 are transcoded as 1920p
34
+ # Videos with height 720 or lesser are transcoded as 720p
35
+ def set_profile_name
36
+ self.profile_name = SCALE_TO_720p
37
+ XMorph::Base.logger.debug("XMorph#set_profile_name#kalpnik: using profile #{self.profile_name}") unless self.profile_name.nil?
38
+ return true
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ REWRAP_COMMAND = "rewrap_command"
3
+ def set_profiles
4
+ self.profiles = {
5
+ REWRAP_COMMAND => "ffmpeg -y -i %{IN} -vcodec copy -map 0:v -streamid 0:2064 -map 0:a:0 -streamid 1:2068 -acodec copy -v verbose -vbsf h264_mp4toannexb -y %{OUT}"
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080],
13
+ ALLOWED_WIDTH => [1920],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
24
+ ALLOWED_AUDIO_CODECS => ["aac"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
27
+ }
28
+ end
29
+
30
+ # Rewrap rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = REWRAP_COMMAND
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#LIG: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "ffmpeg -y -i %{IN} -vf \"fps=fps=29.970000,scale=1920x1080\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 15000000 -minrate:v 15000000 -maxrate:v 15000000 -bufsize:v 30000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 16711200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT}"
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9", "16:10"],
12
+ ALLOWED_HEIGHT => [720, 1080, 2160],
13
+ ALLOWED_WIDTH => [1280, 1920, 3840],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 2],
24
+ ALLOWED_AUDIO_CODECS => ["pcm", "aac"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#peopletv: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ 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} -vf \"fps=fps=25.000000,scale=1920x1080\" -filter_complex \"[0:a:0][0:a:1]amerge=inputs=2[aout0]\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 12000000 -minrate:v 12000000 -maxrate:v 12000000 -bufsize:v 24000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map [\"aout0\"] -muxrate 13411200 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
7
+ STEREO => "ffmpeg -y -i %{IN} -vf \"fps=fps=25.000000,scale=1920x1080\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -vb 12000000 -minrate:v 12000000 -maxrate:v 12000000 -bufsize:v 24000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 13411200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{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, 4, 8],
26
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm"],
27
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
28
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
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#rewind: using profile #{self.profile_name}") unless self.profile_name.nil?
47
+ return true
48
+ end
49
+
50
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "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 12000000 -minrate:v 12000k -maxrate:v 12000k -bufsize:v 24000k -muxrate 13000k -x264opts nal-hrd=cbr -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1"
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080],
13
+ ALLOWED_WIDTH => [1920],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 4, 8],
24
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#rooster-teeth: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ def set_profiles
4
+ self.profiles = {
5
+ "4_3_720_stereo" => "ffmpeg -y -i %{IN} -vf \"fps=fps=25,scale=720x576\" -pix_fmt yuv420p -vcodec h264 -g 12 -bf 2 -x264opts nal-hrd=cbr -profile:v high -flags +ilme+ildct -top 1 -vb 8000000 -minrate:v 8000000 -maxrate:v 8000000 -bufsize:v 16000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -map 0:v -map 0:a:0 -muxrate 9011200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1",
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["4:3"],
12
+ ALLOWED_HEIGHT => [576],
13
+ ALLOWED_WIDTH => [720],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
24
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
27
+ }
28
+ end
29
+
30
+ #profiles are classified based on height, aspect ratio and number of audio channels in a track.
31
+ def set_profile_name
32
+ self.profile_name = "4_3_720_stereo"
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#sabatv: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+
37
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "ffmpeg -y -i %{IN} -s 1920x1080 -vcodec h264 -profile:v high -r 25 -g 13 -pix_fmt yuv420p -bf 2 -vb 11000000 -map 0:v -streamid 0:2064 -acodec libfdk_aac -ac 2 -ar 48000 -profile:a aac_low -ab 192k -filter_complex [0:1][0:2]amerge=inputs=2[aout0] -map [aout0] -streamid 1:2068 -metadata:s:a:0 language=ENG %{OUT}",
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080],
13
+ ALLOWED_WIDTH => [1920],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 2, 8 ],
24
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm", "mpeg audio"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#scripps-cp: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,68 @@
1
+ class Transcode < XMorph::Base
2
+
3
+ HIGH_DEFINITION = "HIGH_DEFINITION"
4
+ STANDARD_DEFINITION = "STANDARD_DEFINITION"
5
+
6
+ def set_profiles
7
+ self.profiles = {
8
+ HIGH_DEFINITION => "ffmpeg -y -i %{IN} -vf \"fps=fps=29.970000,scale=1920x1080,setdar=dar=16/9\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -vb 12000000 -minrate:v 12000000 -maxrate:v 12000000 -bufsize:v 24000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -ar 48000 -map 0:v -map 0:a:0 -muxrate 13411200 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1",
9
+ STANDARD_DEFINITION => "ffmpeg -y -i %{IN} -vf \"fps=fps=29.970000,scale=720x480,setdar=dar=4/3\" -pix_fmt yuv420p -vcodec h264 -g 13 -bf 2 -x264opts nal-hrd=cbr -profile:v high -vb 8000000 -minrate:v 8000000 -maxrate:v 8000000 -bufsize:v 24000000 -acodec libfdk_aac -profile:a aac_low -ab 192k -ar 48000 -map 0:v -map 0:a:0 -muxrate 8600000 -streamid 0:2064 -streamid 1:2068 -vsync 1 -async 1 %{OUT} 2>&1"
10
+ }
11
+ end
12
+
13
+ def video_checks
14
+ {
15
+ ALLOWED_ASPECT_RATIO => IGNORE,
16
+ ALLOWED_HEIGHT => (1..1080),
17
+ ALLOWED_WIDTH => (1..1920),
18
+ ALLOWED_FRAME_RATE => IGNORE,
19
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
20
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
21
+ }
22
+ end
23
+
24
+ def audio_checks
25
+ {
26
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
27
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
28
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm", "mpeg audio"],
29
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
30
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
31
+ }
32
+ end
33
+
34
+ # Classification is based on Video Resoltion
35
+ # HD Videos & 720P Videos are transcoded as 1920x1080 with 16:9 Aspect Ratio
36
+ # SD Videos are transcoded as 720x480 with 4:3 Aspect Ratio
37
+ # Aspect Ratio is forced as 16:9 & 4:3 for HD & SD respectively
38
+ def set_profile_name
39
+ self.profile_name = nil
40
+ mediainfo = self.mediainfo_output
41
+ video_info = mediainfo["Video"]
42
+ aspect_ratio = video_info["Display_aspect_ratio"]
43
+ height = (video_info["Original_height"] || video_info["Height"]).split("pixels")[0].gsub(/ /,"")
44
+ width = (video_info["Original_width"] || video_info["Width"]).split("pixels")[0].gsub(/ /,"")
45
+
46
+ XMorph::Base.logger.debug("XMorph#set_profile_name#shoutfactory: Got Aspect Ratio: #{aspect_ratio}, Height: #{height}, Width: #{width}")
47
+ if height.present? and width.present?
48
+ # HD assets
49
+ if (width.to_i == 1920) and (height.to_i == 1080)
50
+ self.profile_name = HIGH_DEFINITION
51
+ # 720P assets are upscaled to HD asset
52
+ elsif (width.to_i == 1280) and (height.to_i == 720)
53
+ self.profile_name = HIGH_DEFINITION
54
+ # Non HD & 720P assets are forced to SD
55
+ elsif (width.to_i > 0) and (height.to_i > 0) and (width.to_i < 1920) and (height.to_i < 1080)
56
+ self.profile_name = STANDARD_DEFINITION
57
+ else
58
+ self.error = "Got Unexpected Resolution #{width}x#{height}. No transcoding profile available for this."
59
+ XMorph::Base.logger.debug("XMorph#set_profile_name#shoutfactory: Got something unexpected! No Transcoding profile is available for this.")
60
+ return false
61
+ end
62
+ XMorph::Base.logger.debug("XMorph#set_profile_name#shoutfactory: Converting the file to #{self.profile_name}")
63
+ else
64
+ self.error = "Couldn't find Resolution of the Video correctly"
65
+ end
66
+ return true
67
+ end
68
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "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 18000k -minrate:v 18000k -maxrate:v 18000k -bufsize:v 36000k -muxrate 19000k -x264opts nal-hrd=cbr:force-cfr=1 -pes_payload_size 16 -streamid 0:2064 -streamid 1:2068 %{OUT} 2>&1",
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080, 2160],
13
+ ALLOWED_WIDTH => [1920, 3840],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1],
24
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [2],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#tastemade: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ class Transcode < XMorph::Base
2
+ DEFAULT = "default"
3
+ def set_profiles
4
+ self.profiles = {
5
+ DEFAULT => "ffmpeg -y -i %{IN} -s 1920x1080 -vcodec h264 -profile:v high -r 25 -g 13 -pix_fmt yuv420p -bf 2 -vb 11000000 -map 0:v -streamid 0:2064 -acodec libfdk_aac -ac 2 -ar 48000 -profile:a aac_low -ab 192k -filter_complex [0:1][0:2]amerge=inputs=2[aout0] -map [aout0] -streamid 1:2068 -metadata:s:a:0 language=ENG %{OUT}",
6
+ }
7
+ end
8
+
9
+ def video_checks
10
+ {
11
+ ALLOWED_ASPECT_RATIO => ["16:9"],
12
+ ALLOWED_HEIGHT => [1080],
13
+ ALLOWED_WIDTH => [1920],
14
+ ALLOWED_FRAME_RATE => IGNORE,
15
+ ALLOWED_VIDEO_BIT_RATE => IGNORE, #Mbps
16
+ ALLOWED_SCAN_TYPE => IGNORE, #all downcased
17
+ }
18
+ end
19
+
20
+ def audio_checks
21
+ {
22
+ PRESENCE_OF_AUDIO_TRACK => VALIDATE,
23
+ ALLOWED_NUMBER_OF_AUDIO_TRACKS => [1, 7, 8],
24
+ ALLOWED_AUDIO_CODECS => ["aac", "pcm", "dolby e"],
25
+ ALLOWED_AUDIO_BIT_RATE => IGNORE,
26
+ ALLOWED_NUMBER_OF_AUDIO_CHANNELS => [1, 2, 6],
27
+ }
28
+ end
29
+
30
+ # Same transcode rule is applied for all assets.
31
+ def set_profile_name
32
+ self.profile_name = DEFAULT
33
+ XMorph::Base.logger.debug("XMorph#set_profile_name#tern-cp: using profile #{self.profile_name}") unless self.profile_name.nil?
34
+ return true
35
+ end
36
+ end