mpv-ipc 5.0.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/LICENSE +21 -0
- data/README.md +140 -0
- data/lib/mpv_ass/color.rb +111 -0
- data/lib/mpv_ass/span.rb +121 -0
- data/lib/mpv_ass/text.rb +91 -0
- data/lib/mpv_ass.rb +3 -0
- data/lib/mpv_ipc/client.rb +529 -0
- data/lib/mpv_ipc/exceptions.rb +55 -0
- data/lib/mpv_ipc/multi_queue.rb +76 -0
- data/lib/mpv_ipc/server.rb +122 -0
- data/lib/mpv_ipc/session.rb +170 -0
- data/lib/mpv_ipc/utils.rb +19 -0
- data/lib/mpv_ipc/version.rb +6 -0
- data/lib/mpv_ipc.rb +4 -0
- metadata +81 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2e7d0c0d23fc7f57e54fa0c0425686e20c6fd08c0002ca1c3569ab9d7aabab68
|
|
4
|
+
data.tar.gz: d63982804801f0831ab131ce860e601c2ae7908f30d79c2f3781d256da50c9b9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c00ca5d89ffc2343b378ccee7a3013847d931b17b8cbbf0743c517b3825b20c2c4df13660d6eb4db99d9e63ef0005287f963df62d85eb577e9241d51c341359f
|
|
7
|
+
data.tar.gz: 28388a0ae21f8d550d1d42d5974db247bce0f28ce6efdeed94f09cd9f8e1813ac175adf0b8d438aef8af0ee8ddb8cfb3425886cdd72165fb586d795640c16f03
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 William Woodruff <william @ tuffbizz.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
mpv-ipc
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
Start or connect to the mpv media player and control it via IPC.
|
|
5
|
+
|
|
6
|
+
A Ruby library that provides a simple interface for interacting with
|
|
7
|
+
[mpv](https://mpv.io) via its JSON IPC protocol.
|
|
8
|
+
|
|
9
|
+
This gem supports multiple usage patterns:
|
|
10
|
+
- starting and managing an mpv instance (IPC server + connected client),
|
|
11
|
+
- connecting to an already running mpv process as a plain IPC client,
|
|
12
|
+
- writing Ruby-based mpv scripts that are automatically launched at startup.
|
|
13
|
+
|
|
14
|
+
### Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
$ gem install mpv-ipc
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This gem requires [mpv](https://mpv.io) to be installed separately.
|
|
21
|
+
|
|
22
|
+
### Usage
|
|
23
|
+
|
|
24
|
+
For full documentation, please see the [RubyDocs](https://www.rubydoc.info/gems/mpv-ipc).
|
|
25
|
+
|
|
26
|
+
Check out mpv's property [documentation](https://mpv.io/manual/stable/#properties)
|
|
27
|
+
for more details on supported properties and their usage.
|
|
28
|
+
|
|
29
|
+
#### Standalone session
|
|
30
|
+
|
|
31
|
+
This gem can be used to create a standalone mpv session, which starts
|
|
32
|
+
and manages its own mpv instance and communicates with it via JSON IPC.
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
require "mpv_ipc"
|
|
36
|
+
|
|
37
|
+
# Initialize a new mpv session with both a Server and a Client
|
|
38
|
+
mpv = MPV::Session.new
|
|
39
|
+
|
|
40
|
+
# Observe changes in properties
|
|
41
|
+
mpv.observe_property("volume") do |prop_event|
|
|
42
|
+
puts "Volume changed to: #{prop_event.data}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Interact with mpv
|
|
46
|
+
mpv.get_property "pause"
|
|
47
|
+
mpv.set_property "volume", 50.0
|
|
48
|
+
mpv.command "loadfile", "video.mkv"
|
|
49
|
+
|
|
50
|
+
sleep 10
|
|
51
|
+
|
|
52
|
+
# Exit mpv gracefully
|
|
53
|
+
mpv.quit!
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Internally, `MPV::Session` instantiates and wires together an `MPV::Server`
|
|
57
|
+
and an `MPV::Client`.
|
|
58
|
+
|
|
59
|
+
#### IPC client
|
|
60
|
+
|
|
61
|
+
Alternatively, the library can be used as a plain JSON IPC client to connect
|
|
62
|
+
to an already running mpv process. This makes it suitable for both:
|
|
63
|
+
- external control tools that attach to an existing mpv instance, and
|
|
64
|
+
- scripts started and managed by mpv, communicating with it over IPC.
|
|
65
|
+
|
|
66
|
+
To use the gem as an mpv script, place the Ruby file in mpv's script configuration
|
|
67
|
+
directory (e.g. `$HOME/.config/mpv/scripts`) with a `.run` suffix.
|
|
68
|
+
It will automatically start the script at launch and provide the script
|
|
69
|
+
with an IPC connection via `--mpv-ipc-fd`.
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
#!/usr/bin/ruby
|
|
73
|
+
|
|
74
|
+
require "mpv_ipc/client"
|
|
75
|
+
|
|
76
|
+
# Connect to an existing mpv process via its IPC socket
|
|
77
|
+
mpv = MPV::Client.new("/var/run/mpv.socket")
|
|
78
|
+
|
|
79
|
+
# Or initialize a Client using the IPC connection provided by mpv
|
|
80
|
+
# when running as an mpv-managed script (via --mpv-ipc-fd)
|
|
81
|
+
# mpv = MPV::Client.script
|
|
82
|
+
|
|
83
|
+
# Add a listener for the "seek" event
|
|
84
|
+
mpv.register_event_listener("seek") do |event|
|
|
85
|
+
pos = mpv.get_property!("percent-pos")
|
|
86
|
+
mpv.command("show-text", "Pos: %.2f%%" % pos)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Register keybindings for zooming
|
|
90
|
+
mpv.register_keybindings("+", "-") do |key_event|
|
|
91
|
+
if key_event.hold?
|
|
92
|
+
zoom = mpv.get_property!("video-zoom")
|
|
93
|
+
mpv.set_property!("video-zoom", zoom.send(key_event.key, 0.1).clamp(-4, 4))
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Observe changes in the "video-zoom" property
|
|
98
|
+
mpv.observe_property("video-zoom") do |prop_event|
|
|
99
|
+
mpv.command("show-text", "Zoom: %.0f%%" % (2 ** prop_event.data * 100))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Wait until the connection closes
|
|
103
|
+
mpv.wait
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
All event-related callbacks are executed sequentially on the same dedicated
|
|
107
|
+
internal thread to preserve event order. Handlers that may take longer
|
|
108
|
+
can delegate their work to another thread or a new one.
|
|
109
|
+
|
|
110
|
+
#### OSD messages
|
|
111
|
+
|
|
112
|
+
For more advanced overlays, you can also create and edit styled OSD messages
|
|
113
|
+
using the bundled Ass text helpers, with custom fonts, colors, text styles,
|
|
114
|
+
alignment, and other formatting.
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
title = Ass::Span.new("Now playing")
|
|
118
|
+
title.bold.size(28).color(:gold).outline(2, :black)
|
|
119
|
+
|
|
120
|
+
body = Ass::Span.new("Interstellar")
|
|
121
|
+
body.italic.size(24).color(:white).outline(2, :black)
|
|
122
|
+
|
|
123
|
+
text = Ass::Text.new(title, "\n", body).align(:top_right)
|
|
124
|
+
id = mpv.create_osd_message(text)
|
|
125
|
+
|
|
126
|
+
body.content = "Inception"
|
|
127
|
+
mpv.edit_osd_message(id, text)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Compatibility
|
|
131
|
+
|
|
132
|
+
This library currently targets Unix-like systems and has been tested on Linux.
|
|
133
|
+
Some features depend on Unix-specific IPC and process behavior, so Windows
|
|
134
|
+
compatibility has not been implemented or tested yet.
|
|
135
|
+
|
|
136
|
+
This gem is based on the original [ruby-mpv](https://github.com/woodruffw/ruby-mpv)
|
|
137
|
+
project and the extended [fork](https://github.com/pigoz/ruby-mpv).
|
|
138
|
+
|
|
139
|
+
Although this implementation differs from the original,
|
|
140
|
+
it remains partially compatible with its API.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ass
|
|
4
|
+
# Represents an ASS color.
|
|
5
|
+
class Color
|
|
6
|
+
PRESETS = {
|
|
7
|
+
# grayscale
|
|
8
|
+
black: [ 0, 0, 0],
|
|
9
|
+
carbon: [ 64, 64, 64],
|
|
10
|
+
gray: [128, 128, 128],
|
|
11
|
+
silver: [192, 192, 192],
|
|
12
|
+
white: [255, 255, 255],
|
|
13
|
+
|
|
14
|
+
# primary
|
|
15
|
+
red: [255, 0, 0],
|
|
16
|
+
green: [ 0, 255, 0],
|
|
17
|
+
blue: [ 0, 0, 255],
|
|
18
|
+
|
|
19
|
+
# secondary
|
|
20
|
+
yellow: [255, 255, 0],
|
|
21
|
+
magenta: [255, 0, 255],
|
|
22
|
+
cyan: [ 0, 255, 255],
|
|
23
|
+
|
|
24
|
+
# vivid
|
|
25
|
+
orange: [255, 128, 0],
|
|
26
|
+
gold: [255, 192, 0],
|
|
27
|
+
purple: [128, 0, 255],
|
|
28
|
+
turquoise: [ 0, 255, 128],
|
|
29
|
+
|
|
30
|
+
# pastel
|
|
31
|
+
pink: [255, 128, 255],
|
|
32
|
+
sky: [128, 255, 255],
|
|
33
|
+
mint: [128, 255, 128],
|
|
34
|
+
vanilla: [255, 255, 128],
|
|
35
|
+
coral: [255, 128, 128],
|
|
36
|
+
|
|
37
|
+
# shade
|
|
38
|
+
maroon: [128, 0, 0],
|
|
39
|
+
forest: [ 0, 128, 0],
|
|
40
|
+
navy: [ 0, 0, 128],
|
|
41
|
+
teal: [ 0, 128, 128],
|
|
42
|
+
plum: [128, 0, 128],
|
|
43
|
+
olive: [128, 128, 0],
|
|
44
|
+
brown: [128, 64, 0],
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
# Gets the RGBA component values.
|
|
48
|
+
# @return [Array<Integer>] red, green, blue and alpha codes
|
|
49
|
+
attr_reader :codes
|
|
50
|
+
alias_method :to_a, :codes
|
|
51
|
+
|
|
52
|
+
# Creates an ASS::Color.
|
|
53
|
+
# @param color [Array<Integer>, Symbol] preset symbol or custom color codes
|
|
54
|
+
# Color codes are given as [red, green, blue, alpha] in the range 0..255.
|
|
55
|
+
# Alpha defaults to 0, meaning fully opaque, while 255 means fully transparent.
|
|
56
|
+
def initialize(color)
|
|
57
|
+
set(color)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Changes the color value.
|
|
61
|
+
# @param color [Array<Integer>, Symbol] preset symbol or custom color codes
|
|
62
|
+
# Color codes are given as [red, green, blue, alpha] in the range 0..255.
|
|
63
|
+
# Alpha defaults to 0, meaning fully opaque, while 255 means fully transparent.
|
|
64
|
+
# @return [self]
|
|
65
|
+
def set(color)
|
|
66
|
+
color = PRESETS.fetch(color) if color.is_a?(Symbol)
|
|
67
|
+
@codes = color.to_a.values_at(0..3).map{ |code| code.to_i.clamp(0, 255) }
|
|
68
|
+
self
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Changes the red value.
|
|
72
|
+
# @param code [Integer] red channel value in the range 0..255
|
|
73
|
+
# @return [self]
|
|
74
|
+
def red(code)
|
|
75
|
+
@codes[0] = code.to_i.clamp(0, 255)
|
|
76
|
+
self
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Changes the green value.
|
|
80
|
+
# @param code [Integer] green channel value in the range 0..255
|
|
81
|
+
# @return [self]
|
|
82
|
+
def green(code)
|
|
83
|
+
@codes[1] = code.to_i.clamp(0, 255)
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Changes the blue value.
|
|
88
|
+
# @param code [Integer] blue channel value in the range 0..255
|
|
89
|
+
# @return [self]
|
|
90
|
+
def blue(code)
|
|
91
|
+
@codes[2] = code.to_i.clamp(0, 255)
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Changes the alpha value.
|
|
96
|
+
# @param code [Integer] alpha channel value in the range 0..255
|
|
97
|
+
# 0 means fully opaque, while 255 means fully transparent
|
|
98
|
+
# @return [self]
|
|
99
|
+
def alpha(code)
|
|
100
|
+
@codes[3] = code.to_i.clamp(0, 255)
|
|
101
|
+
self
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Converts the color to ASS syntax.
|
|
105
|
+
# @return [String] ASS color representation
|
|
106
|
+
def to_script
|
|
107
|
+
codes = @codes.last.zero? ? @codes[0..-2] : @codes
|
|
108
|
+
"&H#{codes.reverse.map{ |code| "%02X" % code }.join}&"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/mpv_ass/span.rb
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "color"
|
|
4
|
+
|
|
5
|
+
module Ass
|
|
6
|
+
# Represents a styled ASS text fragment.
|
|
7
|
+
class Span
|
|
8
|
+
# Gets or changes the plain text fragment content.
|
|
9
|
+
# @return [String] plain text content
|
|
10
|
+
attr_accessor :content
|
|
11
|
+
alias_method :to_s, :content
|
|
12
|
+
|
|
13
|
+
# Creates an ASS::Span text fragment.
|
|
14
|
+
# @param content [String] plain text content
|
|
15
|
+
def initialize(content=nil)
|
|
16
|
+
@content = content
|
|
17
|
+
@tags = {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Sets the font name.
|
|
21
|
+
# @param name [String] font family name
|
|
22
|
+
# @return [self]
|
|
23
|
+
def font(name)
|
|
24
|
+
@tags["fn"] = name.to_s
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Sets bold text rendering.
|
|
29
|
+
# @param value [Boolean] whether bold styling is enabled
|
|
30
|
+
# @return [self]
|
|
31
|
+
def bold(value=true)
|
|
32
|
+
@tags["b"] = value ? 1 : 0
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Sets italic text rendering.
|
|
37
|
+
# @param value [Boolean] whether italic styling is enabled
|
|
38
|
+
# @return [self]
|
|
39
|
+
def italic(value=true)
|
|
40
|
+
@tags["i"] = value ? 1 : 0
|
|
41
|
+
self
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sets underline text rendering.
|
|
45
|
+
# @param value [Boolean] whether underline styling is enabled
|
|
46
|
+
# @return [self]
|
|
47
|
+
def underline(value=true)
|
|
48
|
+
@tags["u"] = value ? 1 : 0
|
|
49
|
+
self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Sets strikethrough text rendering.
|
|
53
|
+
# @param value [Boolean] whether strikethrough styling is enabled
|
|
54
|
+
# @return [self]
|
|
55
|
+
def strike(value=true)
|
|
56
|
+
@tags["s"] = value ? 1 : 0
|
|
57
|
+
self
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Sets the font size.
|
|
61
|
+
# @param value [Integer] font size
|
|
62
|
+
# @return [self]
|
|
63
|
+
def size(value)
|
|
64
|
+
@tags["fs"] = value.to_i
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Sets the font color.
|
|
69
|
+
# @param value [Ass::Color, Array<Integer>, Symbol] font color
|
|
70
|
+
# @return [self]
|
|
71
|
+
def color(value)
|
|
72
|
+
@tags["1c"] = value.is_a?(Color) ? value : Color.new(value)
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Sets the outline thickness and color.
|
|
77
|
+
# @param size [Integer] outline thickness value
|
|
78
|
+
# @param color [Ass::Color, Array<Integer>, Symbol] outline color value
|
|
79
|
+
# @return [self]
|
|
80
|
+
def outline(size, color)
|
|
81
|
+
@tags["3c"] = color.is_a?(Color) ? color : Color.new(color)
|
|
82
|
+
@tags["bord"] = size.to_i
|
|
83
|
+
self
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Sets the shadow size.
|
|
87
|
+
# @param size [Integer] shadow size value
|
|
88
|
+
# @return [self]
|
|
89
|
+
def shadow(size)
|
|
90
|
+
@tags["shad"] = size.to_i
|
|
91
|
+
self
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Sets the blur strength.
|
|
95
|
+
# @param strength [Numeric] blur strength value
|
|
96
|
+
# @return [self]
|
|
97
|
+
def blur(strength)
|
|
98
|
+
@tags["blur"] = strength.to_f
|
|
99
|
+
self
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Removes all style tags.
|
|
103
|
+
# @return [self]
|
|
104
|
+
def bare
|
|
105
|
+
@tags.clear
|
|
106
|
+
self
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Converts the text fragment to ASS syntax.
|
|
110
|
+
# @return [String] ASS text fragment representation
|
|
111
|
+
def to_script
|
|
112
|
+
tags = @tags.map do |(key, value)|
|
|
113
|
+
value = value.to_script if value.is_a?(Color)
|
|
114
|
+
"\\#{key}#{value}"
|
|
115
|
+
end
|
|
116
|
+
head, tail = "{#{tags.join}}", "{\\r}" unless tags.empty?
|
|
117
|
+
content = @content.to_s.gsub("\\", "\\\\").gsub("{", "\\{").gsub("}", "\\}").gsub("\n", "\\N")
|
|
118
|
+
"#{head}#{content}#{tail}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
data/lib/mpv_ass/text.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "span"
|
|
4
|
+
|
|
5
|
+
module Ass
|
|
6
|
+
# Represents an ASS text containing styled fragments with layout tags.
|
|
7
|
+
class Text
|
|
8
|
+
ALIGN = {
|
|
9
|
+
top_left: 7, top: 8, top_right: 9,
|
|
10
|
+
left: 4, center: 5, right: 6,
|
|
11
|
+
bottom_left: 1, bottom: 2, bottom_right: 3,
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
# Creates an ASS::Text.
|
|
15
|
+
# @param spans [Array<Ass::Span, String>] initial text fragments
|
|
16
|
+
def initialize(*spans)
|
|
17
|
+
@tags = {}
|
|
18
|
+
@spans = []
|
|
19
|
+
add(*spans)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Adds new fragments to the current text.
|
|
23
|
+
# @param spans [Array<Ass::Span, String>] text fragments to append
|
|
24
|
+
# @return [self]
|
|
25
|
+
def add(*spans)
|
|
26
|
+
spans.each{ |span| @spans << (span.is_a?(Span) ? span : Span.new(span)) }
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Replaces the current text fragments.
|
|
31
|
+
# @param spans [Array<Ass::Span, String>] new text fragments
|
|
32
|
+
# @return [self]
|
|
33
|
+
def set(*spans)
|
|
34
|
+
@spans.clear
|
|
35
|
+
add(*spans)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Gets the current text fragments.
|
|
39
|
+
# @return [Array<Ass::Span>] text fragments
|
|
40
|
+
def get()
|
|
41
|
+
@spans.dup.freeze
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sets the absolute position of the text.
|
|
45
|
+
# @param x [Numeric] horizontal coordinate
|
|
46
|
+
# @param y [Numeric] vertical coordinate
|
|
47
|
+
# @return [self]
|
|
48
|
+
def position(x, y)
|
|
49
|
+
@tags["pos"] = x.round(2), y.round(2)
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Sets the alignment anchor of the text.
|
|
54
|
+
# @param value [Integer, Symbol] 1..9 number or symbolic alignment name
|
|
55
|
+
# @return [self]
|
|
56
|
+
def align(value)
|
|
57
|
+
@tags["an"] = value.is_a?(Symbol) ? ALIGN.fetch(value) : value.to_i
|
|
58
|
+
self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Removes all layout tags.
|
|
62
|
+
# @return [self]
|
|
63
|
+
def bare
|
|
64
|
+
@tags.clear
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Converts the text to ASS syntax.
|
|
69
|
+
# @return [String] ASS text representation
|
|
70
|
+
def to_script
|
|
71
|
+
tags = @tags.map do |(key, value)|
|
|
72
|
+
value = "(#{value.join(",")})" if value.is_a?(Array)
|
|
73
|
+
"\\#{key}#{value}"
|
|
74
|
+
end
|
|
75
|
+
head = "{#{tags.join}}" unless tags.empty?
|
|
76
|
+
"#{head}#{@spans.map(&:to_script).join}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns the plain text content of each fragment.
|
|
80
|
+
# @return [Array<String>] plain text fragments
|
|
81
|
+
def to_a
|
|
82
|
+
@spans.map(&:to_s)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Returns the full plain text content.
|
|
86
|
+
# @return [String] concatenated plain text
|
|
87
|
+
def to_s
|
|
88
|
+
to_a.join
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/mpv_ass.rb
ADDED