arthropod_hls_video_encoder 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +64 -0
- data/README.md +78 -0
- data/arthropod_hls_video_encoder.gemspec +29 -0
- data/bin/arthropod_hls_video_encoder +44 -0
- data/lib/arthropod_hls_video_encoder/encoder.rb +158 -0
- data/lib/arthropod_hls_video_encoder/version.rb +3 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8311820e563fed91a93536b6ef5defa75b560ab8d68d02bbcfc9ee32d851ea6c
|
4
|
+
data.tar.gz: 8fe7ad465fb6f41cba32b3f58d673e47b6703978b2c6f9e979749a4dcd41041d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd0f75b5521288300a26fbebcf17b2051381abe7629e601ac3ce3b670f559dcd89b3852ee069137d00fbb38975de1f66136c0074ffb08b6574ae23d678447a08
|
7
|
+
data.tar.gz: 104d79c41ca986d505a2bb911ea8aa3bcc74302b4200e40cf1b2fa028e3c4e1a2dd456ca69bec8dce7ae766b754bd345a318df474711f678401cb7351def542c
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
arthropod_hls_video_encoder (0.0.1)
|
5
|
+
arthropod (= 0.0.2)
|
6
|
+
aws-sdk-sqs
|
7
|
+
fog-aws
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
arthropod (0.0.2)
|
13
|
+
aws-sdk-sqs
|
14
|
+
aws-eventstream (1.0.3)
|
15
|
+
aws-partitions (1.251.0)
|
16
|
+
aws-sdk-core (3.84.0)
|
17
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
18
|
+
aws-partitions (~> 1, >= 1.239.0)
|
19
|
+
aws-sigv4 (~> 1.1)
|
20
|
+
jmespath (~> 1.0)
|
21
|
+
aws-sdk-sqs (1.23.1)
|
22
|
+
aws-sdk-core (~> 3, >= 3.71.0)
|
23
|
+
aws-sigv4 (~> 1.1)
|
24
|
+
aws-sigv4 (1.1.0)
|
25
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
26
|
+
builder (3.2.3)
|
27
|
+
byebug (11.0.1)
|
28
|
+
excon (0.70.0)
|
29
|
+
fog-aws (3.5.2)
|
30
|
+
fog-core (~> 2.1)
|
31
|
+
fog-json (~> 1.1)
|
32
|
+
fog-xml (~> 0.1)
|
33
|
+
ipaddress (~> 0.8)
|
34
|
+
fog-core (2.1.2)
|
35
|
+
builder
|
36
|
+
excon (~> 0.58)
|
37
|
+
formatador (~> 0.2)
|
38
|
+
mime-types
|
39
|
+
fog-json (1.2.0)
|
40
|
+
fog-core
|
41
|
+
multi_json (~> 1.10)
|
42
|
+
fog-xml (0.1.3)
|
43
|
+
fog-core
|
44
|
+
nokogiri (>= 1.5.11, < 2.0.0)
|
45
|
+
formatador (0.2.5)
|
46
|
+
ipaddress (0.8.3)
|
47
|
+
jmespath (1.4.0)
|
48
|
+
mime-types (3.3)
|
49
|
+
mime-types-data (~> 3.2015)
|
50
|
+
mime-types-data (3.2019.1009)
|
51
|
+
mini_portile2 (2.4.0)
|
52
|
+
multi_json (1.14.1)
|
53
|
+
nokogiri (1.10.7)
|
54
|
+
mini_portile2 (~> 2.4.0)
|
55
|
+
|
56
|
+
PLATFORMS
|
57
|
+
ruby
|
58
|
+
|
59
|
+
DEPENDENCIES
|
60
|
+
arthropod_hls_video_encoder!
|
61
|
+
byebug
|
62
|
+
|
63
|
+
BUNDLED WITH
|
64
|
+
2.0.2
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Arthropod-hls-video-encoder
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
```
|
6
|
+
gem install arthropod_hls_video_encoder
|
7
|
+
```
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
Just run it with the required arguments.
|
12
|
+
```shell
|
13
|
+
$ arthropod_hls_video_encoder -h
|
14
|
+
|
15
|
+
Usage: arthropod_hls_video_encoder [options]
|
16
|
+
-q, --queue [string] SQS queue name
|
17
|
+
-i, --access-key-id [string] AWS access key ID, default to the AWS_ACCESS_KEY_ID environment variable
|
18
|
+
-k, --secret-access-key [string] AWS secret access key, default to the AWS_SECRET_ACCESS_KEY environment variable
|
19
|
+
-r, --region [string] AWS region, default to the AWS_REGION environment variable
|
20
|
+
```
|
21
|
+
|
22
|
+
Example of client side call:
|
23
|
+
```ruby
|
24
|
+
result = Arthropod::Client.push(queue_name: "hls_video_encoder", body: {
|
25
|
+
video_url: "https://s3-#{ENV['S3_REGION']}.amazonaws.com/#{ENV['S3_BUCKET']}/#{medium.temporary_key}",
|
26
|
+
root_dir: Digest::SHA1.hexdigest("#{ENV["SECURE_UPLOADER_KEY"]}#{medium.uuid}").insert(3, '/'),
|
27
|
+
aws_access_key_id: ENV['S3_ACCESS_KEY_ID'],
|
28
|
+
aws_secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
|
29
|
+
region: ENV['S3_REGION'],
|
30
|
+
endpoint: ENV['S3_ENDPOINT'],
|
31
|
+
host: ENV['S3_HOST'],
|
32
|
+
bucket: ENV['S3_BUCKET'],
|
33
|
+
profiles: [
|
34
|
+
{
|
35
|
+
codec: "libx264",
|
36
|
+
bandwidth: 1500000,
|
37
|
+
resolution: 720,
|
38
|
+
name: 'high',
|
39
|
+
},
|
40
|
+
{
|
41
|
+
codec: "libx264",
|
42
|
+
bandwidth: 800000,
|
43
|
+
resolution: 720,
|
44
|
+
name: 'low'
|
45
|
+
}
|
46
|
+
]
|
47
|
+
})
|
48
|
+
```
|
49
|
+
|
50
|
+
* `video_url`: the URL of the video you want to transcode to HLS
|
51
|
+
* `root`: the destination directory in your bucket
|
52
|
+
* `aws_access_key_id`: an AWS access key to access your bucket
|
53
|
+
* `aws_secret_access_key`: an AWS secret access key to access your bucket
|
54
|
+
* `region`: the region of your bucket
|
55
|
+
* `endpoint`: the endpoint of your S3 instance if you have one (useful for Minio)
|
56
|
+
* `host`: the host of your S3 instance if you have one (useful for Minio)
|
57
|
+
* `bucket`: your bucket name
|
58
|
+
* `profiles`: the HLS profile you want to generate
|
59
|
+
|
60
|
+
The result object is a follow.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
{
|
64
|
+
key: "[string]",
|
65
|
+
thumbnail_key: "[string]",
|
66
|
+
small_thumbnail_key: "[string]",
|
67
|
+
preview_key: "[string]",
|
68
|
+
duration: "[string]"
|
69
|
+
}
|
70
|
+
```
|
71
|
+
|
72
|
+
* `key`: the key the root HLS file in your bucket
|
73
|
+
* `thumbnail_key`: the key of the auto-generated thumbnail (the thumbnail is taken at half the video time)
|
74
|
+
* `small_thumbnail_key`: same thing, but with a smaller thumbnail
|
75
|
+
* `preview_key`: a GIF preview of your video
|
76
|
+
* `duration`: the duration of the video
|
77
|
+
|
78
|
+
*Both the input and output are very opiniated and follow my needs*
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "arthropod_hls_video_encoder/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = "arthropod_hls_video_encoder"
|
9
|
+
gem.version = ArthropodHlsVideoEncoder::VERSION
|
10
|
+
gem.authors = ["Victor Goya"]
|
11
|
+
gem.email = ["goya.victor@gmail.com"]
|
12
|
+
gem.description = "HLS video encoder using Arthropod"
|
13
|
+
gem.summary = "HLS video encoder using Arthropod"
|
14
|
+
|
15
|
+
gem.files = `git ls-files -z`.split("\x0")
|
16
|
+
gem.executables = %w(arthropod_hls_video_encoder)
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.bindir = 'bin'
|
19
|
+
|
20
|
+
gem.licenses = ["MIT"]
|
21
|
+
|
22
|
+
gem.required_ruby_version = "~> 2.0"
|
23
|
+
|
24
|
+
gem.add_dependency 'arthropod', '= 0.0.2'
|
25
|
+
gem.add_dependency 'aws-sdk-sqs'
|
26
|
+
gem.add_dependency 'fog-aws'
|
27
|
+
|
28
|
+
gem.add_development_dependency "byebug"
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'aws-sdk-sqs'
|
5
|
+
require 'arthropod'
|
6
|
+
require 'arthropod_hls_video_encoder/encoder'
|
7
|
+
|
8
|
+
options = {}
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
11
|
+
|
12
|
+
opts.on("-q", "--queue [string]", "SQS queue name") do |q|
|
13
|
+
options[:queue] = q
|
14
|
+
end
|
15
|
+
opts.on("-i", "--access-key-id [string]", "AWS access key ID, default to the AWS_ACCESS_KEY_ID environment variable") do |i|
|
16
|
+
options[:access_key_id] = i
|
17
|
+
end
|
18
|
+
opts.on("-k", "--secret-access-key [string]", "AWS secret access key, default to the AWS_SECRET_ACCESS_KEY environment variable") do |k|
|
19
|
+
options[:secret_access_key] = k
|
20
|
+
end
|
21
|
+
opts.on("-r", "--region [string]", "AWS region, default to the AWS_REGION environment variable") do |r|
|
22
|
+
options[:region] = r
|
23
|
+
end
|
24
|
+
end.parse!
|
25
|
+
|
26
|
+
client = Aws::SQS::Client.new({
|
27
|
+
access_key_id: options[:access_key_id] || ENV["AWS_ACCESS_KEY_ID"],
|
28
|
+
secret_access_key: options[:secret_access_key] || ENV["AWS_SECRET_ACCESS_KEY"],
|
29
|
+
region: options[:region] || ENV["AWS_REGION"],
|
30
|
+
})
|
31
|
+
|
32
|
+
Arthropod::Server.pull(client: client, queue_name: options[:queue]) do |request|
|
33
|
+
ArthropodHlsVideoEncoder::Encoder.new({
|
34
|
+
video_url: request.body["video_url"],
|
35
|
+
root_dir: request.body["root_dir"],
|
36
|
+
aws_access_key_id: request.body["aws_access_key_id"],
|
37
|
+
aws_secret_access_key: request.body["aws_secret_access_key"],
|
38
|
+
region: request.body["region"],
|
39
|
+
endpoint: request.body["endpoint"],
|
40
|
+
host: request.body["host"],
|
41
|
+
bucket: request.body["bucket"],
|
42
|
+
profiles: request.body["profiles"]
|
43
|
+
}).perform!
|
44
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'json'
|
3
|
+
require 'securerandom'
|
4
|
+
require 'fog/aws'
|
5
|
+
|
6
|
+
module ArthropodHlsVideoEncoder
|
7
|
+
class Encoder
|
8
|
+
attr_reader :video_url, :aws_access_key_id, :aws_secret_access_key, :region, :endpoint, :host, :bucket, :profiles, :job_id, :root_dir
|
9
|
+
|
10
|
+
def initialize(video_url:, root_dir:, aws_access_key_id:, aws_secret_access_key:, region:, endpoint:, host:, bucket:, profiles:)
|
11
|
+
@video_url = video_url
|
12
|
+
@root_dir = root_dir
|
13
|
+
@aws_access_key_id = aws_access_key_id
|
14
|
+
@aws_secret_access_key = aws_secret_access_key
|
15
|
+
@region = region
|
16
|
+
@endpoint = endpoint
|
17
|
+
@host = host
|
18
|
+
@bucket = bucket
|
19
|
+
@profiles = profiles
|
20
|
+
@job_id = SecureRandom.uuid
|
21
|
+
end
|
22
|
+
|
23
|
+
def perform!
|
24
|
+
Dir.mktmpdir do |wdir|
|
25
|
+
@wdir = wdir
|
26
|
+
|
27
|
+
download_input!
|
28
|
+
|
29
|
+
{
|
30
|
+
key: perform_video_encoding!,
|
31
|
+
thumbnail_key: get_thumbnail!,
|
32
|
+
small_thumbnail_key: get_small_thumbnail!,
|
33
|
+
preview_key: get_preview!,
|
34
|
+
duration: get_duration!
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def download_input!
|
40
|
+
unless File.exists? input_path
|
41
|
+
call_command("curl #{Shellwords.escape(video_url)} -s -o #{input_path}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def perform_video_encoding!
|
46
|
+
# Reencode
|
47
|
+
ffmpeg_configurations = profiles.map { |profile| ffmpeg_configuration_for(profile) }.join(" ")
|
48
|
+
|
49
|
+
call_command("ffmpeg -i #{input_path} -pass 1 #{ffmpeg_configurations}")
|
50
|
+
call_command("ffmpeg -i #{input_path} -pass 2 #{ffmpeg_configurations}")
|
51
|
+
|
52
|
+
# create index file
|
53
|
+
indices = profiles.map do |profile|
|
54
|
+
[
|
55
|
+
"#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=#{profile["bandwidth"]}",
|
56
|
+
"#{profile["name"]}_#{job_id}.m3u8"
|
57
|
+
]
|
58
|
+
end
|
59
|
+
File.open("#{@wdir}/index.m3u8", 'w') { |f| f.write("#EXTM3U\n" + indices.flatten.join("\n")) }
|
60
|
+
|
61
|
+
# Upload to storage
|
62
|
+
Dir["#{@wdir}/*.{ts,m3u8}"].each do |path|
|
63
|
+
upload(path, "#{root_dir}/#{File.basename(path)}")
|
64
|
+
end
|
65
|
+
|
66
|
+
"#{root_dir}/index.m3u8"
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_thumbnail!
|
70
|
+
call_command "ffmpeg -i #{input_path} -vcodec mjpeg -vframes 1 -filter:v scale=\"1080:-1\" -q:v 10 -an -f rawvideo -ss #{video_middle} #{thumbnail_path}"
|
71
|
+
|
72
|
+
"#{root_dir}/thumbnail.jpg".tap do |key|
|
73
|
+
upload(thumbnail_path, key)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_small_thumbnail!
|
78
|
+
call_command "ffmpeg -i #{input_path} -vcodec mjpeg -vframes 1 -filter:v scale=\"640:-1\" -q:v 10 -an -f rawvideo -ss #{video_middle} #{small_thumbnail_path}"
|
79
|
+
|
80
|
+
"#{root_dir}/small_thumbnail.jpg".tap do |key|
|
81
|
+
upload(small_thumbnail_path, key)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_preview!
|
86
|
+
call_command "ffmpeg -y -ss #{video_middle} -t 3 -i #{input_path} -vf fps=10,scale=320:-1:flags=lanczos,palettegen #{palette_path}"
|
87
|
+
call_command "ffmpeg -ss #{video_middle} -t 3 -i #{input_path} -i #{palette_path} -filter_complex \"fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse\" #{preview_path}"
|
88
|
+
|
89
|
+
"#{root_dir}/preview.gif".tap do |key|
|
90
|
+
upload(preview_path, key)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_duration!
|
95
|
+
output = JSON.parse(`ffprobe -of json -show_format_entry name -show_format #{input_path} -loglevel quiet`)
|
96
|
+
output["format"]["duration"].to_i
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
def input_path
|
102
|
+
Shellwords.escape("#{@wdir}/input")
|
103
|
+
end
|
104
|
+
|
105
|
+
def thumbnail_path
|
106
|
+
Shellwords.escape("#{@wdir}/thumbnail.jpeg")
|
107
|
+
end
|
108
|
+
|
109
|
+
def small_thumbnail_path
|
110
|
+
Shellwords.escape("#{@wdir}/small_thumbnail.jpeg")
|
111
|
+
end
|
112
|
+
|
113
|
+
def preview_path
|
114
|
+
Shellwords.escape("#{@wdir}/preview.gif")
|
115
|
+
end
|
116
|
+
|
117
|
+
def palette_path
|
118
|
+
Shellwords.escape("#{@wdir}/palette.png")
|
119
|
+
end
|
120
|
+
|
121
|
+
def video_middle
|
122
|
+
Shellwords.escape(`ffmpeg -i #{input_path} 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F ':' '{print ($3+$2*60+$1*3600)/2}'`.chomp)
|
123
|
+
end
|
124
|
+
|
125
|
+
def call_command(command)
|
126
|
+
puts command
|
127
|
+
system(command)
|
128
|
+
raise if $?.to_i != 0
|
129
|
+
end
|
130
|
+
|
131
|
+
def ffmpeg_configuration_for(profile)
|
132
|
+
"-vcodec #{profile["codec"]} -acodec aac -strict -2 -q:a 5 -ac 1 -r 25 -profile:v baseline -vf scale='trunc(oh*a/2)*2:#{profile["resolution"]}' -preset slow -b:v #{profile["bandwidth"]} -maxrate #{profile["bandwidth"]} -pix_fmt yuv420p -flags -global_header -hls_time 10 -hls_list_size 0 #{@wdir}/#{profile["name"]}_#{job_id}.m3u8"
|
133
|
+
end
|
134
|
+
|
135
|
+
def storage
|
136
|
+
@storage ||= Fog::Storage.new({
|
137
|
+
provider: 'AWS',
|
138
|
+
aws_access_key_id: aws_access_key_id,
|
139
|
+
aws_secret_access_key: aws_secret_access_key,
|
140
|
+
region: region,
|
141
|
+
endpoint: endpoint,
|
142
|
+
host: host,
|
143
|
+
path_style: true
|
144
|
+
})
|
145
|
+
@storage.directories.get(bucket)
|
146
|
+
end
|
147
|
+
|
148
|
+
def upload(path, key)
|
149
|
+
open(path) do |file|
|
150
|
+
storage.files.create({
|
151
|
+
key: key,
|
152
|
+
body: file,
|
153
|
+
public: true
|
154
|
+
})
|
155
|
+
end.public_url
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arthropod_hls_video_encoder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Goya
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: arthropod
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-sdk-sqs
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fog-aws
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: HLS video encoder using Arthropod
|
70
|
+
email:
|
71
|
+
- goya.victor@gmail.com
|
72
|
+
executables:
|
73
|
+
- arthropod_hls_video_encoder
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- README.md
|
81
|
+
- arthropod_hls_video_encoder.gemspec
|
82
|
+
- bin/arthropod_hls_video_encoder
|
83
|
+
- lib/arthropod_hls_video_encoder/encoder.rb
|
84
|
+
- lib/arthropod_hls_video_encoder/version.rb
|
85
|
+
homepage:
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '2.0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubygems_version: 3.0.3
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: HLS video encoder using Arthropod
|
108
|
+
test_files: []
|