Skip to content

Commit adc4a7b

Browse files
authored
Merge pull request #114 from samvera-labs/wiggle_room
Allow for lowering completeness threshold on ffmpeg adapter
2 parents 34c0828 + 3e12b95 commit adc4a7b

File tree

11 files changed

+314
-1
lines changed

11 files changed

+314
-1
lines changed

lib/active_encode/engine_adapters/ffmpeg_adapter.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class FfmpegAdapter
1111
MEDIAINFO_PATH = ENV["MEDIAINFO_PATH"] || "mediainfo"
1212
FFMPEG_PATH = ENV["FFMPEG_PATH"] || "ffmpeg"
1313

14+
class_attribute :completeness_threshold
15+
1416
def create(input_url, options = {})
1517
# Decode file uris for ffmpeg (mediainfo works either way)
1618
case input_url
@@ -111,7 +113,7 @@ def find(id, opts = {})
111113
encode.state = :completed
112114
elsif cancelled? encode.id
113115
encode.state = :cancelled
114-
elsif encode.percent_complete < 100
116+
elsif encode.percent_complete < (completeness_threshold || 100)
115117
encode.errors.prepend("Encoding has completed but the output duration is shorter than the input")
116118
encode.state = :failed
117119
end

spec/fixtures/ffmpeg/incomplete-id/error.log

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<MediaInfo
3+
xmlns="https://mediaarea.net/mediainfo"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
6+
version="2.0">
7+
<creatingLibrary version="18.05" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
8+
<media ref="/home/pdinh/Downloads/videoshort.mp4">
9+
<track type="General">
10+
<VideoCount>1</VideoCount>
11+
<AudioCount>1</AudioCount>
12+
<FileExtension>mp4</FileExtension>
13+
<Format>MPEG-4</Format>
14+
<Format_Profile>Base Media</Format_Profile>
15+
<CodecID>mp42</CodecID>
16+
<FileSize>199160</FileSize>
17+
<Duration>6.315</Duration>
18+
<OverallBitRate_Mode>VBR</OverallBitRate_Mode>
19+
<OverallBitRate>252301</OverallBitRate>
20+
<FrameRate>23.719</FrameRate>
21+
<FrameCount>149</FrameCount>
22+
<StreamSize>5679</StreamSize>
23+
<HeaderSize>160</HeaderSize>
24+
<DataSize>193489</DataSize>
25+
<FooterSize>5511</FooterSize>
26+
<IsStreamable>No</IsStreamable>
27+
<Encoded_Date>UTC 2010-09-23 00:37:25</Encoded_Date>
28+
<Tagged_Date>UTC 2010-09-23 00:37:27</Tagged_Date>
29+
<File_Modified_Date>UTC 2017-12-14 19:29:35</File_Modified_Date>
30+
<File_Modified_Date_Local>2017-12-14 14:29:35</File_Modified_Date_Local>
31+
<Encoded_Application>HandBrake 0.9.4 2009112300</Encoded_Application>
32+
</track>
33+
<track type="Video">
34+
<StreamOrder>0</StreamOrder>
35+
<ID>1</ID>
36+
<Format>AVC</Format>
37+
<Format_Profile>Main</Format_Profile>
38+
<Format_Level>1.1</Format_Level>
39+
<Format_Settings_CABAC>Yes</Format_Settings_CABAC>
40+
<Format_Settings_RefFrames>2</Format_Settings_RefFrames>
41+
<CodecID>avc1</CodecID>
42+
<Duration>6.282</Duration>
43+
<BitRate>74477</BitRate>
44+
<Width>200</Width>
45+
<Height>110</Height>
46+
<Stored_Width>208</Stored_Width>
47+
<Stored_Height>112</Stored_Height>
48+
<Sampled_Width>200</Sampled_Width>
49+
<Sampled_Height>110</Sampled_Height>
50+
<PixelAspectRatio>1.000</PixelAspectRatio>
51+
<DisplayAspectRatio>1.818</DisplayAspectRatio>
52+
<Rotation>0.000</Rotation>
53+
<FrameRate_Mode>VFR</FrameRate_Mode>
54+
<FrameRate>23.719</FrameRate>
55+
<FrameRate_Minimum>12.500</FrameRate_Minimum>
56+
<FrameRate_Maximum>24.390</FrameRate_Maximum>
57+
<FrameRate_Original>24.000</FrameRate_Original>
58+
<FrameCount>149</FrameCount>
59+
<ColorSpace>YUV</ColorSpace>
60+
<ChromaSubsampling>4:2:0</ChromaSubsampling>
61+
<BitDepth>8</BitDepth>
62+
<ScanType>Progressive</ScanType>
63+
<StreamSize>58482</StreamSize>
64+
<Encoded_Library>x264 - core 79 r1347 5ddd61b</Encoded_Library>
65+
<Encoded_Library_Name>x264</Encoded_Library_Name>
66+
<Encoded_Library_Version>core 79 r1347 5ddd61b</Encoded_Library_Version>
67+
<Encoded_Library_Settings>cabac=1 / ref=2 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=6 / psy=1 / psy_rd=1.0:0.0 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=0 / cqm=0 / deadzone=21,11 / chroma_qp_offset=-2 / threads=3 / nr=0 / decimate=1 / mbaff=0 / constrained_intra=0 / bframes=2 / b_pyramid=0 / b_adapt=1 / b_bias=0 / direct=1 / wpredb=0 / wpredp=2 / keyint=240 / keyint_min=24 / scenecut=40 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=25.5 / qcomp=0.60 / qpmin=10 / qpmax=51 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00</Encoded_Library_Settings>
68+
<Encoded_Date>UTC 2010-09-23 00:37:25</Encoded_Date>
69+
<Tagged_Date>UTC 2010-09-23 00:37:27</Tagged_Date>
70+
<colour_range>Limited</colour_range>
71+
<colour_description_present>Yes</colour_description_present>
72+
<colour_primaries>BT.601 NTSC</colour_primaries>
73+
<transfer_characteristics>BT.709</transfer_characteristics>
74+
<matrix_coefficients>BT.601</matrix_coefficients>
75+
</track>
76+
<track type="Audio">
77+
<StreamOrder>1</StreamOrder>
78+
<ID>2</ID>
79+
<Format>AAC</Format>
80+
<Format_Profile>LC</Format_Profile>
81+
<CodecID>mp4a-40-2</CodecID>
82+
<Duration>6.315</Duration>
83+
<BitRate_Mode>VBR</BitRate_Mode>
84+
<BitRate>171030</BitRate>
85+
<BitRate_Maximum>201736</BitRate_Maximum>
86+
<Channels>1</Channels>
87+
<ChannelPositions>Front: C</ChannelPositions>
88+
<ChannelLayout>C</ChannelLayout>
89+
<SamplesPerFrame>1024</SamplesPerFrame>
90+
<SamplingRate>48000</SamplingRate>
91+
<SamplingCount>303120</SamplingCount>
92+
<FrameRate>46.875</FrameRate>
93+
<FrameCount>296</FrameCount>
94+
<Compression_Mode>Lossy</Compression_Mode>
95+
<StreamSize>134999</StreamSize>
96+
<StreamSize_Proportion>0.67784</StreamSize_Proportion>
97+
<Title>Stereo</Title>
98+
<Encoded_Date>UTC 2010-09-23 00:37:25</Encoded_Date>
99+
<Tagged_Date>UTC 2010-09-23 00:37:27</Tagged_Date>
100+
</track>
101+
</media>
102+
</MediaInfo>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<MediaInfo
3+
xmlns="https://mediaarea.net/mediainfo"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
6+
version="2.0">
7+
<creatingLibrary version="18.05" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
8+
<media ref="spec/fixtures/ffmpeg/completed-id/low.mp4">
9+
<track type="General">
10+
<VideoCount>1</VideoCount>
11+
<AudioCount>1</AudioCount>
12+
<FileExtension>mp4</FileExtension>
13+
<Format>MPEG-4</Format>
14+
<Format_Profile>Base Media</Format_Profile>
15+
<CodecID>isom</CodecID>
16+
<FileSize>125403</FileSize>
17+
<Duration>6.336</Duration>
18+
<OverallBitRate>158337</OverallBitRate>
19+
<FrameRate>24.000</FrameRate>
20+
<FrameCount>150</FrameCount>
21+
<StreamSize>5648</StreamSize>
22+
<HeaderSize>40</HeaderSize>
23+
<DataSize>119763</DataSize>
24+
<FooterSize>5600</FooterSize>
25+
<IsStreamable>No</IsStreamable>
26+
<File_Modified_Date>UTC 2018-09-07 17:36:26</File_Modified_Date>
27+
<File_Modified_Date_Local>2018-09-07 13:36:26</File_Modified_Date_Local>
28+
<Encoded_Application>Lavf58.12.100</Encoded_Application>
29+
</track>
30+
<track type="Video">
31+
<StreamOrder>0</StreamOrder>
32+
<ID>1</ID>
33+
<Format>AVC</Format>
34+
<Format_Profile>High</Format_Profile>
35+
<Format_Level>1.1</Format_Level>
36+
<Format_Settings_CABAC>Yes</Format_Settings_CABAC>
37+
<Format_Settings_RefFrames>4</Format_Settings_RefFrames>
38+
<CodecID>avc1</CodecID>
39+
<Duration>6.250</Duration>
40+
<BitRate>79302</BitRate>
41+
<Width>200</Width>
42+
<Height>110</Height>
43+
<Stored_Width>208</Stored_Width>
44+
<Stored_Height>112</Stored_Height>
45+
<Sampled_Width>200</Sampled_Width>
46+
<Sampled_Height>110</Sampled_Height>
47+
<PixelAspectRatio>1.000</PixelAspectRatio>
48+
<DisplayAspectRatio>1.818</DisplayAspectRatio>
49+
<Rotation>0.000</Rotation>
50+
<FrameRate_Mode>CFR</FrameRate_Mode>
51+
<FrameRate_Mode_Original>VFR</FrameRate_Mode_Original>
52+
<FrameRate>24.000</FrameRate>
53+
<FrameCount>150</FrameCount>
54+
<ColorSpace>YUV</ColorSpace>
55+
<ChromaSubsampling>4:2:0</ChromaSubsampling>
56+
<BitDepth>8</BitDepth>
57+
<ScanType>Progressive</ScanType>
58+
<StreamSize>61955</StreamSize>
59+
<Encoded_Library>x264 - core 152 r2854 e9a5903</Encoded_Library>
60+
<Encoded_Library_Name>x264</Encoded_Library_Name>
61+
<Encoded_Library_Version>core 152 r2854 e9a5903</Encoded_Library_Version>
62+
<Encoded_Library_Settings>cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=3 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=24 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00</Encoded_Library_Settings>
63+
</track>
64+
<track type="Audio">
65+
<StreamOrder>1</StreamOrder>
66+
<ID>2</ID>
67+
<Format>AAC</Format>
68+
<Format_Profile>LC</Format_Profile>
69+
<Format_Settings_SBR>No (Explicit)</Format_Settings_SBR>
70+
<CodecID>mp4a-40-2</CodecID>
71+
<Duration>6.336</Duration>
72+
<BitRate_Mode>CBR</BitRate_Mode>
73+
<BitRate>72000</BitRate>
74+
<Channels>2</Channels>
75+
<Channels_Original>1</Channels_Original>
76+
<ChannelPositions>Front: C</ChannelPositions>
77+
<ChannelLayout>C</ChannelLayout>
78+
<SamplesPerFrame>1024</SamplesPerFrame>
79+
<SamplingRate>48000</SamplingRate>
80+
<SamplingCount>304128</SamplingCount>
81+
<FrameRate>46.875</FrameRate>
82+
<FrameCount>297</FrameCount>
83+
<Compression_Mode>Lossy</Compression_Mode>
84+
<StreamSize>57800</StreamSize>
85+
<StreamSize_Proportion>0.46091</StreamSize_Proportion>
86+
<Default>Yes</Default>
87+
<AlternateGroup>1</AlternateGroup>
88+
</track>
89+
</media>
90+
</MediaInfo>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<MediaInfo
3+
xmlns="https://mediaarea.net/mediainfo"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd"
6+
version="2.0">
7+
<creatingLibrary version="18.05" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
8+
<media ref="spec/fixtures/ffmpeg/completed-id/low.mp4">
9+
<track type="General">
10+
<VideoCount>1</VideoCount>
11+
<AudioCount>1</AudioCount>
12+
<FileExtension>mp4</FileExtension>
13+
<Format>MPEG-4</Format>
14+
<Format_Profile>Base Media</Format_Profile>
15+
<CodecID>isom</CodecID>
16+
<FileSize>125403</FileSize>
17+
<Duration>6.336</Duration>
18+
<OverallBitRate>158337</OverallBitRate>
19+
<FrameRate>24.000</FrameRate>
20+
<FrameCount>150</FrameCount>
21+
<StreamSize>5648</StreamSize>
22+
<HeaderSize>40</HeaderSize>
23+
<DataSize>119763</DataSize>
24+
<FooterSize>5600</FooterSize>
25+
<IsStreamable>No</IsStreamable>
26+
<File_Modified_Date>UTC 2018-09-07 17:36:26</File_Modified_Date>
27+
<File_Modified_Date_Local>2018-09-07 13:36:26</File_Modified_Date_Local>
28+
<Encoded_Application>Lavf58.12.100</Encoded_Application>
29+
</track>
30+
<track type="Video">
31+
<StreamOrder>0</StreamOrder>
32+
<ID>1</ID>
33+
<Format>AVC</Format>
34+
<Format_Profile>High</Format_Profile>
35+
<Format_Level>1.1</Format_Level>
36+
<Format_Settings_CABAC>Yes</Format_Settings_CABAC>
37+
<Format_Settings_RefFrames>4</Format_Settings_RefFrames>
38+
<CodecID>avc1</CodecID>
39+
<Duration>6.250</Duration>
40+
<BitRate>79302</BitRate>
41+
<Width>200</Width>
42+
<Height>110</Height>
43+
<Stored_Width>208</Stored_Width>
44+
<Stored_Height>112</Stored_Height>
45+
<Sampled_Width>200</Sampled_Width>
46+
<Sampled_Height>110</Sampled_Height>
47+
<PixelAspectRatio>1.000</PixelAspectRatio>
48+
<DisplayAspectRatio>1.818</DisplayAspectRatio>
49+
<Rotation>0.000</Rotation>
50+
<FrameRate_Mode>CFR</FrameRate_Mode>
51+
<FrameRate_Mode_Original>VFR</FrameRate_Mode_Original>
52+
<FrameRate>24.000</FrameRate>
53+
<FrameCount>150</FrameCount>
54+
<ColorSpace>YUV</ColorSpace>
55+
<ChromaSubsampling>4:2:0</ChromaSubsampling>
56+
<BitDepth>8</BitDepth>
57+
<ScanType>Progressive</ScanType>
58+
<StreamSize>61955</StreamSize>
59+
<Encoded_Library>x264 - core 152 r2854 e9a5903</Encoded_Library>
60+
<Encoded_Library_Name>x264</Encoded_Library_Name>
61+
<Encoded_Library_Version>core 152 r2854 e9a5903</Encoded_Library_Version>
62+
<Encoded_Library_Settings>cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=3 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=24 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=crf / mbtree=1 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00</Encoded_Library_Settings>
63+
</track>
64+
<track type="Audio">
65+
<StreamOrder>1</StreamOrder>
66+
<ID>2</ID>
67+
<Format>AAC</Format>
68+
<Format_Profile>LC</Format_Profile>
69+
<Format_Settings_SBR>No (Explicit)</Format_Settings_SBR>
70+
<CodecID>mp4a-40-2</CodecID>
71+
<Duration>6.336</Duration>
72+
<BitRate_Mode>CBR</BitRate_Mode>
73+
<BitRate>72000</BitRate>
74+
<Channels>2</Channels>
75+
<Channels_Original>1</Channels_Original>
76+
<ChannelPositions>Front: C</ChannelPositions>
77+
<ChannelLayout>C</ChannelLayout>
78+
<SamplesPerFrame>1024</SamplesPerFrame>
79+
<SamplingRate>48000</SamplingRate>
80+
<SamplingCount>304128</SamplingCount>
81+
<FrameRate>46.875</FrameRate>
82+
<FrameCount>297</FrameCount>
83+
<Compression_Mode>Lossy</Compression_Mode>
84+
<StreamSize>57800</StreamSize>
85+
<StreamSize_Proportion>0.46091</StreamSize_Proportion>
86+
<Default>Yes</Default>
87+
<AlternateGroup>1</AlternateGroup>
88+
</track>
89+
</media>
90+
</MediaInfo>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
99999
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
frame=150
2+
fps=0.0
3+
stream_0_0_q=-1.0
4+
bitrate= 158.9kbits/s
5+
total_size=125403
6+
out_time_ms=6000000
7+
out_time=00:00:06.000000
8+
dup_frames=1
9+
drop_frames=0
10+
speed=43.1x
11+
progress=end
Binary file not shown.
Binary file not shown.

spec/integration/ffmpeg_adapter_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
end
3939
let(:completed_job) { find_encode "completed-id" }
4040
let(:completed_with_warnings_job) { find_encode "completed-with-warnings-id" }
41+
let(:incomplete_job) { find_encode "incomplete-id" }
4142
let(:failed_job) { find_encode 'failed-id' }
4243
let(:completed_tech_metadata) do
4344
{
@@ -320,6 +321,21 @@ def find_encode(id)
320321
expect(File).to exist("#{work_dir}/#{subject.id}/exit_status.code")
321322
expect(File.read("#{work_dir}/#{subject.id}/exit_status.code").to_i).to eq(-22)
322323
end
324+
325+
context 'with less than 100 percent completeness' do
326+
subject { incomplete_job }
327+
328+
it { is_expected.to be_failed }
329+
it 'has an error' do
330+
expect(incomplete_job.errors).to include "Encoding has completed but the output duration is shorter than the input"
331+
end
332+
333+
it 'succeeds with a configured completeness threshold' do
334+
allow(ActiveEncode::EngineAdapters::FfmpegAdapter).to receive(:completeness_threshold).and_return(95)
335+
expect(incomplete_job).not_to be_failed
336+
expect(incomplete_job.errors).to be_empty
337+
end
338+
end
323339
end
324340
end
325341

0 commit comments

Comments
 (0)