timestamp_maker 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 01abd157048ff7bdbf8fee5cd139f8e238c48dc82850202aa4f9c7748d7bf8da
4
+ data.tar.gz: 7c94cd8a48aab112d17a48f97112cb5594fd517415518202e0dc6074e1b707a0
5
+ SHA512:
6
+ metadata.gz: 48cf23b7cb6c1526825316f148875a7554371e7e3c2ca5716a3e33b7585277789a7d698d4b0811eb60c59d445af742e16b43a3c454d68365f372f428db245f0a
7
+ data.tar.gz: 9b1d3b546e5a0ac019efb0f46fa2763b40614e0efb406b38e5430d96fbb8540d99b92d7f34fcafe86f19e34fd91b70319ea7240ad9b1c9ee88d1f55c1c021c8b
data/bin/timestamp ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'timestamp_maker'
5
+ require 'optparse'
6
+
7
+ option_parser = OptionParser.new do |opts|
8
+ opts.banner = "Usage: #{__FILE__} INPUT_FILE_PATH OUTPUT_FILE_PATH"
9
+ end
10
+ option_parser.parse!
11
+
12
+ if ARGV.length != 2
13
+ puts option_parser
14
+ exit 1
15
+ end
16
+
17
+ input = ARGV.shift
18
+ output = ARGV.shift
19
+
20
+ TimestampMaker.add_timestamp(input, output)
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'marcel'
4
+ require 'pathname'
5
+ require 'timestamp_maker/video_timestamper'
6
+ require 'timestamp_maker/mime_recognizer'
7
+ require 'timestamp_maker/image_timestamper'
8
+
9
+ module TimestampMaker
10
+ @mime_recognizer = MimeRecognizer
11
+ @image_timestamper = ImageTimestamper
12
+ @video_timestamper = VideoTimestamper
13
+
14
+ class << self
15
+ attr_reader :mime_recognizer, :image_timestamper, :video_timestamper
16
+
17
+ def add_timestamp(input_path, output_path)
18
+ mime_type = mime_recognizer.recognize(input_path)
19
+ processor =
20
+ case mime_type.split('/').first
21
+ when 'image' then image_timestamper
22
+ when 'video' then video_timestamper
23
+ else raise "Unsupported MIME type: ##{mime_type}"
24
+ end
25
+ processor.add_timestamp(input_path, output_path)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'time'
5
+
6
+ module TimestampMaker
7
+ module ImageTimestamper
8
+ def self.add_timestamp(input_path, output_path)
9
+ time_string = creation_time(input_path).iso8601
10
+ command = %W[
11
+ magick convert #{input_path}
12
+ (
13
+ -background rgba(0,0,0,0.7)
14
+ -fill white
15
+ -font Roboto
16
+ -pointsize 32
17
+ -gravity NorthWest
18
+ -splice 1x1
19
+ -gravity SouthEast
20
+ -splice 1x1
21
+ label:#{time_string}
22
+ )
23
+ -gravity NorthWest -geometry +32+32 -composite #{output_path}
24
+ ]
25
+ system(*command, exception: true)
26
+ end
27
+
28
+ def self.creation_time(input_path)
29
+ command = %W[
30
+ magick identify -format %[exif:DateTime*]%[exif:OffsetTime*] #{input_path}
31
+ ]
32
+
33
+ stdout_string, status = Open3.capture2(*command)
34
+ raise unless status.success?
35
+
36
+ parsed = Hash[stdout_string.split("\n").map!{ _1[5..].split('=') }]
37
+
38
+ time_string = parsed['DateTimeOriginal'] || parsed['DateTimeDigitized'] || parsed['DateTime']
39
+ raise 'Cannot find creation time' if time_string.nil?
40
+
41
+ time_offset_string = parsed['OffsetTimeOriginal'] || parsed['OffsetTimeDigitized'] || parsed['OffsetTime'] || 'Z'
42
+
43
+ Time.strptime("#{time_string} #{time_offset_string}", '%Y:%m:%d %H:%M:%S %Z')
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TimestampMaker
4
+ module MimeRecognizer
5
+ def self.recognize(path)
6
+ Marcel::MimeType.for(Pathname.new(path))
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'time'
5
+ require 'open3'
6
+ require 'shellwords'
7
+
8
+ module TimestampMaker
9
+ module VideoTimestamper
10
+ def self.add_timestamp(input_path, output_path)
11
+ creation_timestamp = creation_time(input_path).to_i
12
+ drawtext = %W[
13
+ x=32
14
+ y=32
15
+ font=Roboto
16
+ fontsize=32
17
+ fontcolor=white
18
+ box=1
19
+ boxcolor=black@0.7
20
+ boxborderw=8
21
+ text=%{pts\\\\:localtime\\\\:#{creation_timestamp}}
22
+ ].join(':')
23
+
24
+ command = %W[
25
+ ffmpeg -y -v warning -i #{input_path} -map_metadata 0
26
+ -vf drawtext=#{drawtext}
27
+ #{output_path}
28
+ ]
29
+
30
+ system(*command, exception: true)
31
+ end
32
+
33
+ def self.creation_time(input_path)
34
+ command = %W[
35
+ ffprobe -v warning -print_format json -show_entries format_tags=creation_time #{Shellwords.escape(input_path)}
36
+ ]
37
+ stdout_string, status = Open3.capture2(*command)
38
+ raise unless status.success?
39
+
40
+ parsed = JSON.parse(stdout_string)
41
+ iso8601_string = parsed['format']['tags']['creation_time']
42
+ raise 'Cannot find creation time' if iso8601_string.nil?
43
+
44
+ Time.iso8601(iso8601_string)
45
+ end
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timestamp_maker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Weihang Jian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-07-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: marcel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ description: timestamp_maker is a command-line tool that adds timestamp to images
56
+ and videos.
57
+ email: tonytonyjan@gmail.com
58
+ executables:
59
+ - timestamp
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - bin/timestamp
64
+ - lib/timestamp_maker.rb
65
+ - lib/timestamp_maker/image_timestamper.rb
66
+ - lib/timestamp_maker/mime_recognizer.rb
67
+ - lib/timestamp_maker/video_timestamper.rb
68
+ homepage: https://github.com/tonytonyjan/timestamp_maker
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ source_code_uri: https://github.com/tonytonyjan/timestamp_maker
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.2.22
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: timestamp_maker is a command-line tool that adds timestamp to images and
92
+ videos.
93
+ test_files: []