eikon 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +0 -0
- data/.github/workflows/main.yml +27 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +57 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +183 -0
- data/LICENSE.txt +21 -0
- data/README.md +54 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/tapioca +27 -0
- data/eikon-0.1.0.gem +0 -0
- data/eikon.gemspec +34 -0
- data/lib/eikon/comparator.rb +17 -0
- data/lib/eikon/image_processor.rb +48 -0
- data/lib/eikon/version.rb +4 -0
- data/lib/eikon/video_processor.rb +72 -0
- data/lib/eikon.rb +35 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/byebug.rbi +1041 -0
- data/sorbet/rbi/gems/climate_control.rbi +46 -0
- data/sorbet/rbi/gems/coderay.rbi +92 -0
- data/sorbet/rbi/gems/eikon.rbi +21 -0
- data/sorbet/rbi/gems/ffi.rbi +560 -0
- data/sorbet/rbi/gems/method_source.rbi +64 -0
- data/sorbet/rbi/gems/minitest.rbi +422 -0
- data/sorbet/rbi/gems/pry.rbi +1949 -0
- data/sorbet/rbi/gems/rake.rbi +645 -0
- data/sorbet/rbi/gems/ruby-vips.rbi +656 -0
- data/sorbet/rbi/gems/ruby_jard.rbi +681 -0
- data/sorbet/rbi/gems/terrapin.rbi +116 -0
- data/sorbet/rbi/gems/tty-screen.rbi +66 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +34134 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +17393 -0
- data/sorbet/rbi/sorbet-typed/lib/actionpack/all/actionpack.rbi +1138 -0
- data/sorbet/rbi/sorbet-typed/lib/actionview/all/actionview.rbi +408 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/>=6/activesupport.rbi +37 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +1850 -0
- data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +108 -0
- data/sorbet/rbi/sorbet-typed/lib/railties/>=6.1/railties.rbi +15 -0
- data/sorbet/rbi/sorbet-typed/lib/railties/all/railties.rbi +110 -0
- data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +276 -0
- data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +645 -0
- data/sorbet/rbi/sorbet-typed/lib/rubocop/>=1.8/rubocop.rbi +12 -0
- data/sorbet/rbi/sorbet-typed/lib/rubocop-performance/~>1.6/rubocop-performance.rbi +149 -0
- data/sorbet/rbi/sorbet-typed/lib/rubocop-rails/~>2.5/rubocop-rails.rbi +328 -0
- data/sorbet/rbi/sorbet-typed/lib/thor/all/thor.rbi +905 -0
- data/sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi +32 -0
- data/sorbet/rbi/todo.rbi +15 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +141 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require "sorbet-runtime"
|
3
|
+
require "terrapin"
|
4
|
+
|
5
|
+
module Eikon
|
6
|
+
class VideoProcessor
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { returns(String) }
|
10
|
+
attr_reader :file_name
|
11
|
+
|
12
|
+
sig { params(file_name: String).void }
|
13
|
+
def initialize(file_name)
|
14
|
+
@file_name = T.let(file_name, String)
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { returns(String) }
|
18
|
+
def split_video_into_images
|
19
|
+
file_name = get_file_name(@file_name)
|
20
|
+
|
21
|
+
setup_tmp_folder
|
22
|
+
|
23
|
+
output_folder_path = "tmp/videos/#{file_name}_#{Time.now.utc.strftime("%Y%m%d%H%M%S")}"
|
24
|
+
begin
|
25
|
+
make_dir_command = Terrapin::CommandLine.new("mkdir", ":folder_name")
|
26
|
+
make_dir_command.run(folder_name: output_folder_path)
|
27
|
+
rescue Terrapin::ExitStatusError
|
28
|
+
raise "Folder already exists for this export"
|
29
|
+
end
|
30
|
+
|
31
|
+
# ffmpeg -i pexels-ron-lach-7121125.mp4 -vf fps=10/60 out%d.png
|
32
|
+
line = Terrapin::CommandLine.new("ffmpeg", "-i :file_name -vf fps=10/60 :folder_name")
|
33
|
+
line.run(file_name: @file_name, folder_name: "#{output_folder_path}/#{file_name}_%d.png")
|
34
|
+
output_folder_path
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { params(folder_path: String).returns(T::Array[T::Hash[String, T.any(Integer, String)]]) }
|
38
|
+
def get_frames_dhash(folder_path)
|
39
|
+
# All the file lists start with `.` and `..` so we need to remove those
|
40
|
+
file_names = Dir.entries(folder_path).drop(2)
|
41
|
+
|
42
|
+
dhashes = file_names.map do |file_name|
|
43
|
+
dhash = Eikon.dhash_for_image("#{folder_path}/#{file_name}")
|
44
|
+
{ file_name: file_name, dhash: dhash }
|
45
|
+
end
|
46
|
+
dhashes
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
sig { params(file_name: String).returns(String) }
|
52
|
+
def get_file_name(file_name)
|
53
|
+
file_name_parts = file_name.split(".")
|
54
|
+
file_name_parts.select! { |e| !e.empty? }
|
55
|
+
file_name = file_name_parts.first
|
56
|
+
T.must(T.must(file_name).split("/").last)
|
57
|
+
end
|
58
|
+
|
59
|
+
sig { void }
|
60
|
+
def setup_tmp_folder
|
61
|
+
begin
|
62
|
+
make_dir_command = Terrapin::CommandLine.new("mkdir", "tmp/")
|
63
|
+
make_dir_command.run
|
64
|
+
rescue Terrapin::ExitStatusError; end
|
65
|
+
|
66
|
+
begin
|
67
|
+
make_dir_command = Terrapin::CommandLine.new("mkdir", "tmp/videos")
|
68
|
+
make_dir_command.run
|
69
|
+
rescue Terrapin::ExitStatusError; end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/eikon.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# typed: strict
|
2
|
+
require "eikon/version"
|
3
|
+
require "eikon/comparator"
|
4
|
+
require "eikon/video_processor"
|
5
|
+
require "eikon/image_processor"
|
6
|
+
require "vips"
|
7
|
+
require "ruby_jard"
|
8
|
+
require "sorbet-runtime"
|
9
|
+
|
10
|
+
module Eikon
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
sig { params(filename: T.untyped).returns(String) }
|
16
|
+
def self.dhash_for_image(filename)
|
17
|
+
image = Eikon::ImageProcessor.new(filename)
|
18
|
+
image.preprocess_image
|
19
|
+
image.generate_byte_array
|
20
|
+
image.byte_array
|
21
|
+
end
|
22
|
+
|
23
|
+
sig { params(filename: String).returns(T::Array[T::Hash[String, T.any(Integer, String)]]) }
|
24
|
+
def self.dhash_for_video(filename)
|
25
|
+
video_processor = Eikon::VideoProcessor.new(filename)
|
26
|
+
storage_path = video_processor.split_video_into_images
|
27
|
+
dhashes = video_processor.get_frames_dhash(storage_path)
|
28
|
+
dhashes
|
29
|
+
end
|
30
|
+
|
31
|
+
sig { params(filename_1: String, filename_2: String).returns(Integer) }
|
32
|
+
def self.distance_between_files(filename_1, filename_2)
|
33
|
+
Eikon::Comparator.compare(dhash_for_image(filename_1), dhash_for_image(filename_2))
|
34
|
+
end
|
35
|
+
end
|
data/sorbet/config
ADDED