amagi_transcode 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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