yandex_speech_api 1.1.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
+ SHA1:
3
+ metadata.gz: 503bb8b1169230590382c2bed35232e8c8b0ad8c
4
+ data.tar.gz: b4e5a11c0494ff5b43a3831a44427d7a0b75d26a
5
+ SHA512:
6
+ metadata.gz: 08aedbd6436613262ce70410b9c5b9f0b476dd6a6dd1758f9531a7064518d5827854832c7e9afe8a2cbd1a82f66c5bd436a888377c03ad7ce3a574f2179e5c4a
7
+ data.tar.gz: caecae0b89060595daf24261389e533f67712b48a976da40067d58e11688212ce70a95d42f6208eb3738757e6fd2bfb74d342352a416e0a017fe25d783c54b73
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rake'
6
+
7
+ gemspec
8
+
9
+ group :development do
10
+ gem 'webmock', '~> 2.3.1'
11
+ gem 'rspec', '~> 3.5.0'
12
+ end
13
+
14
+ group :test do
15
+ gem 'coveralls', require: false
16
+ end
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) <2016> Kuzichev Michael
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # YandexSpeechApi [![Gem Version](https://badge.fury.io/rb/yandex_speech_api.svg)](https://badge.fury.io/rb/yandex_speech_api) [![Build Status](https://travis-ci.org/Medvedu/Yandex-Speech-API.svg?branch=master)](https://travis-ci.org/Medvedu/Yandex-Speech-API) [![Code Climate](https://codeclimate.com/github/Medvedu/Yandex-Speech-API/badges/gpa.svg)](https://codeclimate.com/github/Medvedu/Yandex-Speech-API) [![Inline docs](http://inch-ci.org/github/Medvedu/Yandex-Speech-API.svg?branch=master)](http://inch-ci.org/github/Medvedu/Yandex-Speech-API) [![Coverage Status](https://coveralls.io/repos/github/Medvedu/Yandex-Speech-API/badge.svg)](https://coveralls.io/github/Medvedu/Yandex-Speech-API)
2
+
3
+ ## Описание
4
+
5
+ Wrapper для синтезатора речи, основанного на технологиях Yandex SpeechKit Cloud API. Предоставляет собой интерфейс для перевода машинного текста (на русском, английском, украинском или турецком язык) в речь. Может использоваться как для прямого воспроизведения текста, так и для записи речи в файл.
6
+
7
+ ## Установка
8
+
9
+ 1. Перед использованием необходимо получить ключ разработчика. Подробнее на официальном сайте: https://tech.yandex.ru/speechkit/cloud
10
+ 2. Добавьте yandex_speech_api в Gemfile.
11
+ 3. bundle install
12
+ 4. Добавьте в проект:
13
+
14
+ ```ruby
15
+ # ...
16
+ require 'yandex_speech'
17
+ # ...
18
+ ````
19
+
20
+ Воспроизведение звука поддерживается для UNIX-подобных операционных систем (Mac + Linux).
21
+
22
+ ### Примеры использования
23
+
24
+ ### Пример 1
25
+
26
+ _Для начала работы с api достаточно указать ключ:_
27
+
28
+ ```ruby
29
+ key = File.open('secret key/key').readline.strip
30
+
31
+ speaker = YandexSpeechApi::Speaker.init key: key, language: 'russian'
32
+ speaker.save_to_file "Не будите спящего кота."
33
+ ```
34
+
35
+ ### Пример 2
36
+
37
+ _Когда это неоходимо, конструктор позволяет переписывать параметры по умолчанию, например, так можно выбрать язык:_
38
+
39
+ ```ruby
40
+ YandexSpeechApi::Key.global_key = File.open('secret key/key').readline.strip
41
+
42
+ message = "Don't trouble trouble until trouble troubles you"
43
+ speaker = YandexSpeechApi::Speaker.init(voice: :zahar, speed: 0.23)
44
+ speaker.say message
45
+ ```
46
+
47
+ Обратите внимание, передавать key каждый раз нет никакой необходимости. Достаточно один раз установить YandexSpeechApi::Key.global_key.
48
+
49
+ ### Пример 3
50
+
51
+ _Также поддерживаются геттеры и сеттеры:_
52
+
53
+ ```ruby
54
+ key = File.open('secret key/key').readline.strip
55
+
56
+ message = "Як поїдеш в об'їзд, то будеш і на обід, а як навпростець, то увечері."
57
+
58
+ speaker = YandexSpeechApi::Speaker.init
59
+ speaker.key = key
60
+ speaker.voice = 'Alyss'
61
+ speaker.language = 'Ukrain'
62
+ speaker.speed = 1.2
63
+ speaker.emotion = 'good'
64
+ speaker.save_to_file message, '~/downloads/sound'
65
+ ```
66
+
67
+ ### Пример 4
68
+
69
+ _И, наконец, установка параметров через блок:_
70
+
71
+ ```ruby
72
+ key = File.open('secret key/key').readline.strip
73
+ message = "one two three. one two three. one two three four."
74
+
75
+ speaker = YandexSpeechApi::Speaker.init do |s|
76
+ s.key = key
77
+ s.voice = :jane
78
+ s.language = :english
79
+ s.speed = :slow
80
+ s.emotion = :good
81
+ end
82
+
83
+ speaker.say message
84
+ ```
85
+
86
+ ## Примечания
87
+
88
+ 1. За один запрос озвучивается текст, длинной до 2000 знаков.
89
+ 2. Выбирая язык, учтите: вы ограничены его фонетикой, так, например, английский переводчик не умеет озвучивать русские тексты и т.п. (На самом деле это не совсем точно — хотя официальная документация и не рекомендует выставлять некорректные пары язык-текст, в то же время, _русский_ переводчик фактически может воспроизводить английские тексты)
90
+
91
+ ## Зависимости
92
+
93
+ * Ruby 2.0.0 или выше
94
+
95
+ ### Linux-специфичные зависимости:
96
+
97
+ * mpg123
98
+
99
+ ## Лицензия
100
+
101
+ Данный код распространяется под лицензией MIT, подробнее смотрите [LICENSE](./LICENSE). Остальные права принадлежат их владельцам.
@@ -0,0 +1,253 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Wrapper for Yandex Speech API (https://tech.yandex.ru/speechkit).
5
+ #
6
+ # @see https://github.com/Medvedu/Yandex-Speech-API
7
+ # @see README.md
8
+ #
9
+ # @author Kuzichev Michael
10
+ # @license MIT
11
+ module YandexSpeechApi
12
+ require_relative 'yandex_speech/project_structure'
13
+ #
14
+ # Speaker a class that convert English, Ukrain, Russian or Turkey text to
15
+ # speech. Solution based on Yandex SpeechKit technology.
16
+ #
17
+ # @example Basic usage
18
+ # key = File.open('secret key/key').readline.strip
19
+ #
20
+ # speaker = YandexSpeechApi::Speaker.init key: key, language: 'russian'
21
+ # speaker.save_to_file "Не будите спящего кота."
22
+ #
23
+ # @example Hash syntax
24
+ # key = File.open('secret key/key').readline.strip
25
+ # message = "Don't trouble trouble until trouble troubles you"
26
+ #
27
+ # speaker = YandexSpeechApi::Speaker.init({ key: key, language: 'english', voice: :zahar, speed: 0.23 })
28
+ # speaker.say message
29
+ #
30
+ # @example Block syntax
31
+ # key = File.open('secret key/key').readline.strip
32
+ # message = "one two three. one two three. one two three four."
33
+ #
34
+ # speaker = YandexSpeechApi::Speaker.init do |s|
35
+ # s.key = key
36
+ # s.voice = :jane
37
+ # s.language = :english
38
+ # s.speed = :slow
39
+ # s.emotion = :good
40
+ # end
41
+ # speaker.say message
42
+ #
43
+ # Before usage you need to get an api key. It is free for non-commercial
44
+ # purposes (at least for now).
45
+ #
46
+ # You can get this key from official site: https://tech.yandex.ru/speechkit
47
+ #
48
+ # Note: Yandex provide many services throw this site. Your need exactly
49
+ # +Yandex SpeechKit Cloud+ key. Other keys will not work!
50
+ #
51
+ # Do not share this key to third party.
52
+ #
53
+ class Speaker
54
+ class << self
55
+ ##
56
+ # Creates +Speaker+ instance.
57
+ #
58
+ # @param [Proc] callback
59
+ # Used to set object state throw {do ... end} block.
60
+ #
61
+ # @param [HASH] settings
62
+ # Overrides default settings.
63
+ # @option settings [Symbol] :speed (:standard)
64
+ # @see Speaker#speed for details.
65
+ # @option settings [Symbol] :voice (:alyss)
66
+ # @see Speaker#voice for details.
67
+ # @option settings [Symbol] :emotion (:neutral)
68
+ # @see Speaker#emotion for details.
69
+ # @option settings [Symbol] :language (:english)
70
+ # @see Speaker#language for details.
71
+ # @option settings [Symbol] :format (:mp3)
72
+ # @see Speaker#format for details.
73
+ # @option settings [Symbol] :key (:unknown)
74
+ # @see Speaker#key for details.
75
+ #
76
+ # @return [YandexSpeech]
77
+
78
+ def init(settings = {}, &callback)
79
+ new settings, &callback
80
+ end
81
+ end # class << self
82
+
83
+ private_class_method :new
84
+
85
+ ##
86
+ # Determines dictor speech speed.
87
+ #
88
+ # @return [Speed]
89
+
90
+ attr_reader :speed
91
+
92
+ ##
93
+ # Preferred dictor voice.
94
+ #
95
+ # @return [Voice]
96
+
97
+ attr_reader :voice
98
+
99
+ ##
100
+ # How emotional dictor should speak.
101
+ #
102
+ # @return [Emotion]
103
+
104
+ attr_reader :emotion
105
+
106
+ ##
107
+ # Speaker language.
108
+ #
109
+ # Speaker with +russian+ language can't translate, or even synthesize
110
+ # +english+ text (actually it can, but official documentation strongly
111
+ # recommend to select right language for incoming text)
112
+ #
113
+ # @return [Language]
114
+
115
+ attr_reader :language
116
+
117
+ ##
118
+ # How remote server should decode audio data for us.
119
+ #
120
+ # Do not use +:wav+ format for large texts. Result audio file will be
121
+ # too big, and service truncates resulted file.
122
+ #
123
+ # @return [Format]
124
+
125
+ attr_reader :format
126
+
127
+ ##
128
+ # Defines setters for +@voice+, +@language+,+@format+, +@emotion+,
129
+ # +@speed+, +@key+ attributes.
130
+ #
131
+ # @setter #speed=(other)
132
+ # @param [Symbol, Integer, Float] other
133
+ # Expecting values are
134
+ # :slowest, :slow, :standard, :fast, :fastest
135
+ # or any Integer/Float from (0.1)..3 range.
136
+ #
137
+ # @setter #voice=(other)
138
+ # @param [Symbol] other
139
+ # Expecting values are
140
+ # :jane, :oksana, :alyss, :omazh, :zahar, :ermil
141
+ #
142
+ # @setter #emotion=(other)
143
+ # @param [Symbol] other
144
+ # Expecting values are
145
+ # :good, :evil, :neutral
146
+ #
147
+ # @setter #language=(other)
148
+ # @param [Symbol] other
149
+ # Expecting values are
150
+ # :russian, :english, :ukrain, :turkey
151
+ #
152
+ # @setter #format=(other)
153
+ # @param [Symbol] other
154
+ # Expecting values are
155
+ # :mp3, :wav, :opus
156
+ #
157
+ # @setter #key=(new_key)
158
+ # @param [String] new_key
159
+
160
+ %i(voice language format emotion speed key).each do |symbol|
161
+ define_method "#{symbol}=" do |other|
162
+ method_name = __method__.to_s.chop
163
+ klass = YandexSpeechApi.const_get method_name.capitalize
164
+ variable =
165
+ if other.is_a? klass
166
+ other
167
+ else
168
+ klass.new(other)
169
+ end
170
+ instance_variable_set "@#{method_name}", variable
171
+ end
172
+ end
173
+
174
+ ##
175
+ # Speeches text.
176
+ #
177
+ # @example #Say usage
178
+ # key = File.open('secret key/key').readline.strip
179
+ # message = "one two three. one two three. one two three four."
180
+ #
181
+ # speaker = YandexSpeechApi::Speaker.init do |s|
182
+ # s.key = key
183
+ # s.voice = :jane
184
+ # s.language = :english
185
+ # s.speed = :slow
186
+ # s.emotion = :good
187
+ # end
188
+ # speaker.say message
189
+ #
190
+ # @param [String] text
191
+ # Something that should been said.
192
+ #
193
+ # @return [NilClass]
194
+ # You hear the sound.
195
+
196
+ def say(text)
197
+ format = Format.new :mp3
198
+ binary_data = request text, format: format
199
+
200
+ file = Tempfile.new ['yandex_speech_temp_file', ".#{format.type}"]
201
+ file.write binary_data
202
+
203
+ player = MP3_Player.init
204
+ player.play file.path
205
+
206
+ file.close(true) if file
207
+
208
+ return nil
209
+ end
210
+
211
+ ##
212
+ # Saves synthesized voice to audio-file.
213
+ #
214
+ # If +path_to_file+ is empty it saves audio-file to '~/downloads'
215
+ #
216
+ # @example #save_to_file usage
217
+ # key = File.open('secret key/key').readline.strip
218
+ #
219
+ # speaker = YandexSpeechApi::Speaker.init key: key, language: 'russian'
220
+ # speaker.save_to_file "Не будите спящего кота.", 'let_cat_sleep'
221
+ #
222
+ # @param [String] text
223
+ # Something that should been said.
224
+ #
225
+ # @param [String] path_to_file ('~/downloads')
226
+ # Path to new file (without file extension).
227
+ #
228
+ # @return [String]
229
+ # Absolute path to created file.
230
+
231
+ def save_to_file(text, path_to_file = '')
232
+ path_to_file = generate_path if path_to_file.empty?
233
+
234
+ binary_data = request text
235
+ absolute_path = "#{File.expand_path(path_to_file)}.#{format.type}"
236
+ File.open(absolute_path, 'w') { |f| f.write binary_data }
237
+
238
+ return absolute_path
239
+ end
240
+
241
+ private
242
+
243
+ ##
244
+ # Yandex Speech ApiKey.
245
+ #
246
+ # Key is not something that should be shared with any other class. Setter
247
+ # method is public anyway.
248
+ #
249
+ # @return [Key]
250
+
251
+ attr_reader :key
252
+ end # class Speaker
253
+ end # module YandexSpeechApi
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ module Connection # no-doc
5
+ class << self
6
+
7
+ ##
8
+ # Sends :get request.
9
+ #
10
+ # @param [Hash] params
11
+ # @option params [String] :text
12
+ # @option params [Symbol] :format
13
+ # @option params [String] :lang
14
+ # @option params [String] :speaker
15
+ # @option params [Symbol] :emotion
16
+ # @option params [Float] :speed
17
+ # @option params [String, Symbol] :key
18
+ #
19
+ # @exception ConnectionError
20
+ # Raised when responce is not successful.
21
+ #
22
+ # @return [String]
23
+ # Binary data.
24
+
25
+ def send(**params)
26
+ uri = URI.parse URL
27
+ uri.query = URI.encode_www_form params
28
+ response = Net::HTTP.get_response uri
29
+
30
+ case response
31
+ when Net::HTTPSuccess
32
+ return response.body
33
+ else
34
+ raise ConnectionError.new response.code, response.message
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ ##
41
+ # YandexAPI endpoint.
42
+
43
+ URL = "https://tts.voicetech.yandex.net/generate"
44
+ end # class << self
45
+
46
+ ##
47
+ # Raised when connection failed.
48
+
49
+ class ConnectionError < YandexSpeechError
50
+ def initialize(code, message); super "Connection refused by remote server. Error code: '#{code}', Exception message: '#{message}'." end; end
51
+ end # module Connection
52
+ end # module YandexSpeechApi
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module YandexSpeechApi
4
+ class Emotion
5
+
6
+ ##
7
+ # List of allowed emotions
8
+ #
9
+ # @return [Array<String>]
10
+
11
+ def self.list
12
+ %i(evil good neutral)
13
+ end
14
+
15
+ #
16
+ # @return [Symbol]
17
+ # possible values: :evil, :good or :neutral
18
+
19
+ attr_reader :type
20
+
21
+ def initialize(emotion)
22
+ @type = emotion.downcase.to_sym
23
+
24
+ raise EmotionNotAllowed, emotion unless emotion_known? @type
25
+ end
26
+
27
+ private
28
+
29
+ def emotion_known?(emotion)
30
+ Emotion.list.include? emotion
31
+ end
32
+
33
+ ##
34
+ # Raised when unknown emotion has been selected.
35
+
36
+ class EmotionNotAllowed < YandexSpeechError
37
+ def initialize(emotion); super "Emotion '#{emotion}' not allowed for usage. To see list of allowed emotions use Emotion#list" end; end
38
+ end # class Emotion
39
+ end # module YandexSpeechApi