yayvd 0.1.0
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 +7 -0
- data/README.md +110 -0
- data/Rakefile +9 -0
- data/lib/yayvd/config.rb +13 -0
- data/lib/yayvd/error.rb +13 -0
- data/lib/yayvd/executor.rb +20 -0
- data/lib/yayvd/version.rb +5 -0
- data/lib/yayvd/video.rb +69 -0
- data/lib/yayvd.rb +18 -0
- data/mise.toml +2 -0
- data/yayvd.gemspec +26 -0
- metadata +51 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 03e9c133c4903acd5b5e4ca9d1efbc7c8d73068ffd3e90e6f70925b4d6145181
|
|
4
|
+
data.tar.gz: f0de49d56d5143f5dd2d68e631e7a47962e3b75771e23d7e01efb0804293a23a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5075ceacf9303923cc7ee318ac4c7af4d1add0eeb6814909af370d27b060886da771af1b70d95686eb9bdccce0b3637779d2c6013082d19dc2276f2df6b15ea3
|
|
7
|
+
data.tar.gz: 68fa339643827abf48783ef50289a5e2b8617a61bf5bc64ee842db831439d67522642966f5573ec38ecd178eaff5c0981f8e34c746ddc19ed576b6969e6697cd
|
data/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# YAYVD (Yet Another Youtube Video Downloader)
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/yayvd)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**YAYVD** is a developer-friendly Ruby wrapper for [yt-dlp](https://github.com/yt-dlp/yt-dlp). It simplifies the process of downloading videos and audio from YouTube, providing a clean Ruby API while leveraging the power and stability of `yt-dlp`.
|
|
7
|
+
|
|
8
|
+
Designed for both **Humans** (simple API, sensible defaults) and **AI Agents** (structured metadata, predictable errors).
|
|
9
|
+
|
|
10
|
+
## 🚀 Features
|
|
11
|
+
|
|
12
|
+
* **Simple API:** Download video or audio with a single line of code.
|
|
13
|
+
* **Smart Audio:** Automatically extracts high-quality audio, converts to MP3, and embeds metadata (Artist, Title, Cover Art).
|
|
14
|
+
* **Rich Metadata:** Fetch video details (views, duration, upload date) without downloading the file.
|
|
15
|
+
* **Reliable:** Built on top of `yt-dlp`, the industry standard for video extraction.
|
|
16
|
+
* **Configurable:** Customize paths and binary locations easily.
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
Add this line to your application's Gemfile:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
gem 'yayvd'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
And then execute:
|
|
27
|
+
|
|
28
|
+
$ bundle install
|
|
29
|
+
|
|
30
|
+
### System Dependencies
|
|
31
|
+
|
|
32
|
+
YAYVD requires `yt-dlp` and `ffmpeg` (for audio conversion) to be installed on your system.
|
|
33
|
+
|
|
34
|
+
**macOS (Homebrew):**
|
|
35
|
+
```bash
|
|
36
|
+
brew install yt-dlp ffmpeg
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Linux (Debian/Ubuntu):**
|
|
40
|
+
```bash
|
|
41
|
+
sudo apt update
|
|
42
|
+
sudo apt install yt-dlp ffmpeg
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Python (Universal):**
|
|
46
|
+
```bash
|
|
47
|
+
pip install yt-dlp
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 🛠 Usage
|
|
51
|
+
|
|
52
|
+
### Basic Usage
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
require 'yayvd'
|
|
56
|
+
|
|
57
|
+
# Initialize with a YouTube URL
|
|
58
|
+
video = Yayvd::Video.new("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
|
59
|
+
|
|
60
|
+
# 1. Get Metadata (Fast, no download)
|
|
61
|
+
info = video.info
|
|
62
|
+
puts "Title: #{info.title}" # => "Rick Astley - Never Gonna Give You Up"
|
|
63
|
+
puts "Views: #{info.views}" # => 123456789
|
|
64
|
+
puts "Date: #{info.upload_date}" # => <Date: 2009-10-25>
|
|
65
|
+
|
|
66
|
+
# 2. Download Audio (High Quality MP3 + Metadata + Cover Art)
|
|
67
|
+
# Saves to current directory by default
|
|
68
|
+
video.download_audio
|
|
69
|
+
|
|
70
|
+
# 3. Download Video (Best Quality MP4)
|
|
71
|
+
video.download_video
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Advanced Configuration
|
|
75
|
+
|
|
76
|
+
You can configure download paths and binary locations globally:
|
|
77
|
+
|
|
78
|
+
```ruby
|
|
79
|
+
Yayvd.configure do |config|
|
|
80
|
+
config.default_download_path = "/home/user/Downloads"
|
|
81
|
+
config.yt_dlp_path = "/usr/local/bin/yt-dlp" # Optional: Custom binary path
|
|
82
|
+
end
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Custom Output Path per Download
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
video.download_audio(path: "/tmp/music")
|
|
89
|
+
video.download_video(path: "/tmp/videos")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 🤖 AI Context (For LLMs & Agents)
|
|
93
|
+
|
|
94
|
+
If you are an AI agent using this library, here is the mental model:
|
|
95
|
+
|
|
96
|
+
1. **Class:** `Yayvd::Video` is the main entry point.
|
|
97
|
+
2. **Initialization:** `Yayvd::Video.new(url)` is lightweight. It does not make network requests.
|
|
98
|
+
3. **Metadata:** `.info` returns an `OpenStruct`. It caches the result, so calling it multiple times is safe.
|
|
99
|
+
4. **Blocking:** `.download_audio` and `.download_video` are **blocking** operations. They shell out to `yt-dlp`.
|
|
100
|
+
5. **Errors:**
|
|
101
|
+
* `Yayvd::ExecutionError`: Raised if `yt-dlp` fails (e.g., invalid URL, network error).
|
|
102
|
+
* `Yayvd::Error::Messages::YT_DLP_NOT_FOUND`: Raised if the binary is missing.
|
|
103
|
+
|
|
104
|
+
## 🤝 Contributing
|
|
105
|
+
|
|
106
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Lusqinha/YAYVD.
|
|
107
|
+
|
|
108
|
+
## 📝 License
|
|
109
|
+
|
|
110
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/lib/yayvd/config.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yayvd
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :yt_dlp_path, :ffmpeg_path, :default_download_path
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@yt_dlp_path = "yt-dlp" # Tenta usar do PATH por padrão
|
|
9
|
+
@ffmpeg_path = "ffmpeg"
|
|
10
|
+
@default_download_path = Dir.pwd
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/yayvd/error.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yayvd
|
|
4
|
+
class Error < StandardError
|
|
5
|
+
module Messages
|
|
6
|
+
YT_DLP_EXECUTION_FAILED = "Failed to execute yt-dlp"
|
|
7
|
+
YT_DLP_NOT_FOUND = "yt-dlp not found. Please install it to use this gem."
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ExecutionError < Error; end
|
|
12
|
+
class DependencyError < Error; end
|
|
13
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
|
|
5
|
+
module Yayvd
|
|
6
|
+
class Executor
|
|
7
|
+
def execute(args)
|
|
8
|
+
binary = Yayvd.configuration.yt_dlp_path
|
|
9
|
+
cmd = "#{binary} #{args}"
|
|
10
|
+
|
|
11
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
|
12
|
+
|
|
13
|
+
unless status.success?
|
|
14
|
+
raise Yayvd::ExecutionError, "#{Yayvd::Error::Messages::YT_DLP_EXECUTION_FAILED}: #{stderr}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
stdout
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/yayvd/video.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'date'
|
|
4
|
+
require 'ostruct'
|
|
5
|
+
|
|
6
|
+
module Yayvd
|
|
7
|
+
class Video
|
|
8
|
+
attr_reader :url, :metadata
|
|
9
|
+
|
|
10
|
+
def initialize(url, executor: Executor.new)
|
|
11
|
+
@url = url
|
|
12
|
+
@metadata = nil
|
|
13
|
+
@executor = executor
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def info
|
|
17
|
+
return @metadata if @metadata
|
|
18
|
+
|
|
19
|
+
output = run_command("--dump-json")
|
|
20
|
+
raw_data = JSON.parse(output)
|
|
21
|
+
|
|
22
|
+
@metadata = OpenStruct.new(
|
|
23
|
+
title: raw_data["title"],
|
|
24
|
+
duration: raw_data["duration"],
|
|
25
|
+
views: raw_data["view_count"],
|
|
26
|
+
uploader: raw_data["uploader"],
|
|
27
|
+
upload_date: parse_date(raw_data["upload_date"]),
|
|
28
|
+
formats: raw_data["formats"]
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def download_audio(path: nil)
|
|
33
|
+
output_dir = path || Yayvd.configuration.default_download_path
|
|
34
|
+
output_template = File.join(output_dir, "%(title)s.%(ext)s")
|
|
35
|
+
|
|
36
|
+
# -f bestaudio: Best audio source
|
|
37
|
+
# -x: Extract audio
|
|
38
|
+
# --audio-format mp3: Convert to mp3
|
|
39
|
+
# --audio-quality 0: Best VBR quality
|
|
40
|
+
# --embed-metadata: Adds artist, title, etc to the file
|
|
41
|
+
# --embed-thumbnail: Adds video thumbnail as album art
|
|
42
|
+
args = "-f bestaudio -x --audio-format mp3 --audio-quality 0 --embed-metadata --embed-thumbnail -o \"#{output_template}\""
|
|
43
|
+
|
|
44
|
+
run_command(args)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def download_video(quality: :best, path: nil)
|
|
48
|
+
output_dir = path || Yayvd.configuration.default_download_path
|
|
49
|
+
output_template = File.join(output_dir, "%(title)s.%(ext)s")
|
|
50
|
+
|
|
51
|
+
# bestvideo+bestaudio/best: Best video and audio merged
|
|
52
|
+
# --merge-output-format mp4: Ensure final container is mp4
|
|
53
|
+
args = "-f \"bestvideo+bestaudio/best\" --merge-output-format mp4 -o \"#{output_template}\""
|
|
54
|
+
|
|
55
|
+
run_command(args)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def run_command(args)
|
|
61
|
+
full_args = "#{args} \"#{@url}\""
|
|
62
|
+
@executor.execute(full_args)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def parse_date(date_str)
|
|
66
|
+
Date.parse(date_str) rescue nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/yayvd.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "yayvd/version"
|
|
4
|
+
require_relative "yayvd/config"
|
|
5
|
+
require_relative "yayvd/executor"
|
|
6
|
+
require_relative "yayvd/video"
|
|
7
|
+
require_relative "yayvd/error"
|
|
8
|
+
|
|
9
|
+
module Yayvd
|
|
10
|
+
class << self
|
|
11
|
+
attr_accessor :configuration
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.configure
|
|
15
|
+
self.configuration ||= Configuration.new
|
|
16
|
+
yield(configuration)
|
|
17
|
+
end
|
|
18
|
+
end
|
data/mise.toml
ADDED
data/yayvd.gemspec
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/yayvd/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "yayvd"
|
|
7
|
+
spec.version = Yayvd::VERSION
|
|
8
|
+
spec.authors = ["Lucas"]
|
|
9
|
+
spec.email = ["lucas@example.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Yet Another Youtube Video Downloader - A robust Ruby wrapper for yt-dlp"
|
|
12
|
+
spec.description = "A simple Ruby interface for downloading YouTube videos and audio using yt-dlp."
|
|
13
|
+
spec.homepage = "https://github.com/Lusqinha/YAYVD"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 3.0.0"
|
|
16
|
+
|
|
17
|
+
spec.files = Dir.chdir(__dir__) do
|
|
18
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
19
|
+
(File.expand_path(f) == __FILE__) ||
|
|
20
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
spec.bindir = "exe"
|
|
24
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
25
|
+
spec.require_paths = ["lib"]
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: yayvd
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Lucas
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: A simple Ruby interface for downloading YouTube videos and audio using
|
|
13
|
+
yt-dlp.
|
|
14
|
+
email:
|
|
15
|
+
- lucas@example.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- README.md
|
|
21
|
+
- Rakefile
|
|
22
|
+
- lib/yayvd.rb
|
|
23
|
+
- lib/yayvd/config.rb
|
|
24
|
+
- lib/yayvd/error.rb
|
|
25
|
+
- lib/yayvd/executor.rb
|
|
26
|
+
- lib/yayvd/version.rb
|
|
27
|
+
- lib/yayvd/video.rb
|
|
28
|
+
- mise.toml
|
|
29
|
+
- yayvd.gemspec
|
|
30
|
+
homepage: https://github.com/Lusqinha/YAYVD
|
|
31
|
+
licenses:
|
|
32
|
+
- MIT
|
|
33
|
+
metadata: {}
|
|
34
|
+
rdoc_options: []
|
|
35
|
+
require_paths:
|
|
36
|
+
- lib
|
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 3.0.0
|
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
requirements: []
|
|
48
|
+
rubygems_version: 3.6.7
|
|
49
|
+
specification_version: 4
|
|
50
|
+
summary: Yet Another Youtube Video Downloader - A robust Ruby wrapper for yt-dlp
|
|
51
|
+
test_files: []
|