peasy-video 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 722eba8276c2e46c71278324cf6241b474dbe7045b832c63c4b2fc8c42aa0c67
4
+ data.tar.gz: 7be5625b0ce0e2c28304289442db4d0caf3b54f61f58b524578b7f7e91272944
5
+ SHA512:
6
+ metadata.gz: 8238dd89b9833cc17a307113e1dcdcad476e450df424bb02637fa58c1ca87f165959d5e56067ace25aab3fd5f57ca34c01dc567c3006c66a972446e9e2ce2374
7
+ data.tar.gz: 1858f54dc656d40158a81aef5cd7b61b0372640db5dc71db853cf7990994a56c4683a38ee28baf3f5c61f354018610a77d6fe8956f17b85152597af7467d0ba4
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "json"
5
+ require "tempfile"
6
+
7
+ module PeasyVideo
8
+ FORMATS = %w[mp4 webm mkv avi mov gif].freeze
9
+
10
+ module_function
11
+
12
+ def info(path)
13
+ cmd = %W[ffprobe -v quiet -print_format json -show_format -show_streams #{path}]
14
+ out, err, st = Open3.capture3(*cmd)
15
+ raise Error, "ffprobe failed: #{err}" unless st.success?
16
+ data = JSON.parse(out)
17
+ fmt = data["format"] || {}
18
+ vs = (data["streams"] || []).find { |s| s["codec_type"] == "video" } || {}
19
+ {
20
+ duration: fmt["duration"]&.to_f,
21
+ width: vs["width"]&.to_i,
22
+ height: vs["height"]&.to_i,
23
+ fps: eval_fps(vs["r_frame_rate"]),
24
+ codec: vs["codec_name"],
25
+ format: fmt["format_name"],
26
+ bitrate: fmt["bit_rate"]&.to_i,
27
+ size: fmt["size"]&.to_i,
28
+ has_audio: (data["streams"] || []).any? { |s| s["codec_type"] == "audio" },
29
+ }
30
+ end
31
+
32
+ def trim(input, start: 0, duration: nil, end_time: nil, output: nil)
33
+ output ||= input.to_s.sub(/(\.\w+)$/, "_trimmed\\1")
34
+ args = ["ffmpeg", "-y", "-i", input.to_s, "-ss", start.to_s]
35
+ args += ["-t", duration.to_s] if duration
36
+ args += ["-to", end_time.to_s] if end_time
37
+ args << output
38
+ _o, err, st = Open3.capture3(*args)
39
+ raise Error, "trim failed: #{err}" unless st.success?
40
+ output
41
+ end
42
+
43
+ def resize(input, width:, height: nil, output: nil)
44
+ output ||= input.to_s.sub(/(\.\w+)$/, "_resized\\1")
45
+ h = height || -2
46
+ _o, err, st = Open3.capture3("ffmpeg", "-y", "-i", input.to_s, "-vf", "scale=#{width}:#{h}", output)
47
+ raise Error, "resize failed: #{err}" unless st.success?
48
+ output
49
+ end
50
+
51
+ def thumbnail(input, time: 0, output: nil)
52
+ output ||= input.to_s.sub(/\.\w+$/, "_thumb.png")
53
+ _o, err, st = Open3.capture3("ffmpeg", "-y", "-i", input.to_s, "-ss", time.to_s, "-vframes", "1", output)
54
+ raise Error, "thumbnail failed: #{err}" unless st.success?
55
+ output
56
+ end
57
+
58
+ def video_to_gif(input, fps: 10, width: 480, output: nil)
59
+ output ||= input.to_s.sub(/\.\w+$/, ".gif")
60
+ filter = "fps=#{fps},scale=#{width}:-1:flags=lanczos"
61
+ _o, err, st = Open3.capture3("ffmpeg", "-y", "-i", input.to_s, "-vf", filter, output)
62
+ raise Error, "gif conversion failed: #{err}" unless st.success?
63
+ output
64
+ end
65
+
66
+ def extract_audio(input, format: "mp3", output: nil)
67
+ output ||= input.to_s.sub(/\.\w+$/, ".#{format}")
68
+ _o, err, st = Open3.capture3("ffmpeg", "-y", "-i", input.to_s, "-vn", output)
69
+ raise Error, "extract audio failed: #{err}" unless st.success?
70
+ output
71
+ end
72
+
73
+ class Error < StandardError; end
74
+
75
+ def eval_fps(rate_str)
76
+ return nil unless rate_str
77
+ num, den = rate_str.split("/").map(&:to_f)
78
+ den && den > 0 ? (num / den).round(2) : num
79
+ end
80
+ private_class_method :eval_fps
81
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PeasyVideo
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "peasy_video/version"
4
+ require_relative "peasy_video/engine"
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peasy-video
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - PeasyTools
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Video processing library for Ruby — trim, resize, rotate, extract audio,
13
+ generate thumbnails, convert to GIF. FFmpeg-powered with a clean Ruby API.
14
+ email:
15
+ - hello@peasytools.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/peasy_video.rb
21
+ - lib/peasy_video/engine.rb
22
+ - lib/peasy_video/version.rb
23
+ homepage: https://peasyvideo.com
24
+ licenses:
25
+ - MIT
26
+ metadata:
27
+ homepage_uri: https://peasyvideo.com
28
+ source_code_uri: https://github.com/peasytools/peasy-video-rb
29
+ changelog_uri: https://github.com/peasytools/peasy-video-rb/blob/main/CHANGELOG.md
30
+ documentation_uri: https://peasyvideo.com
31
+ bug_tracker_uri: https://github.com/peasytools/peasy-video-rb/issues
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 4.0.3
47
+ specification_version: 4
48
+ summary: Video processing — trim, resize, thumbnails, GIF conversion
49
+ test_files: []