youtube-transcript-rb 0.1.0 → 0.2.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -42
  3. data/lib/youtube_rb/transcript/api.rb +148 -0
  4. data/lib/youtube_rb/transcript/errors.rb +215 -0
  5. data/lib/youtube_rb/transcript/formatters.rb +267 -0
  6. data/lib/youtube_rb/transcript/settings.rb +26 -0
  7. data/lib/youtube_rb/transcript/transcript.rb +237 -0
  8. data/lib/youtube_rb/transcript/transcript_list.rb +168 -0
  9. data/lib/youtube_rb/transcript/transcript_list_fetcher.rb +223 -0
  10. data/lib/youtube_rb/transcript/transcript_parser.rb +81 -0
  11. data/lib/{youtube/transcript/rb → youtube_rb/transcript}/version.rb +2 -4
  12. data/lib/youtube_rb/transcript.rb +35 -0
  13. data/sig/youtube_rb/transcript.rbs +6 -0
  14. data/spec/api_spec.rb +20 -20
  15. data/spec/errors_spec.rb +39 -39
  16. data/spec/formatters_spec.rb +36 -36
  17. data/spec/integration_spec.rb +32 -32
  18. data/spec/settings_spec.rb +16 -16
  19. data/spec/spec_helper.rb +1 -1
  20. data/spec/transcript_list_fetcher_spec.rb +27 -27
  21. data/spec/transcript_list_spec.rb +6 -6
  22. data/spec/transcript_parser_spec.rb +3 -3
  23. data/spec/transcript_spec.rb +16 -16
  24. metadata +12 -12
  25. data/lib/youtube/transcript/rb/api.rb +0 -150
  26. data/lib/youtube/transcript/rb/errors.rb +0 -217
  27. data/lib/youtube/transcript/rb/formatters.rb +0 -269
  28. data/lib/youtube/transcript/rb/settings.rb +0 -28
  29. data/lib/youtube/transcript/rb/transcript.rb +0 -239
  30. data/lib/youtube/transcript/rb/transcript_list.rb +0 -170
  31. data/lib/youtube/transcript/rb/transcript_list_fetcher.rb +0 -225
  32. data/lib/youtube/transcript/rb/transcript_parser.rb +0 -83
  33. data/lib/youtube/transcript/rb.rb +0 -37
  34. data/sig/youtube/transcript/rb.rbs +0 -8
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
- require "youtube/transcript/rb"
4
+ require "youtube_rb/transcript"
5
5
 
6
- RSpec.describe Youtube::Transcript::Rb do
7
- describe Youtube::Transcript::Rb::TranslationLanguage do
6
+ RSpec.describe YoutubeRb::Transcript do
7
+ describe YoutubeRb::Transcript::TranslationLanguage do
8
8
  let(:language) { described_class.new(language: "Spanish", language_code: "es") }
9
9
 
10
10
  describe "#initialize" do
@@ -18,7 +18,7 @@ RSpec.describe Youtube::Transcript::Rb do
18
18
  end
19
19
  end
20
20
 
21
- describe Youtube::Transcript::Rb::TranscriptSnippet do
21
+ describe YoutubeRb::Transcript::TranscriptSnippet do
22
22
  let(:snippet) { described_class.new(text: "Hello world", start: 1.5, duration: 2.0) }
23
23
 
24
24
  describe "#initialize" do
@@ -58,7 +58,7 @@ RSpec.describe Youtube::Transcript::Rb do
58
58
  end
59
59
  end
60
60
 
61
- describe Youtube::Transcript::Rb::FetchedTranscript do
61
+ describe YoutubeRb::Transcript::FetchedTranscript do
62
62
  let(:transcript) do
63
63
  described_class.new(
64
64
  video_id: "test_video",
@@ -68,8 +68,8 @@ RSpec.describe Youtube::Transcript::Rb do
68
68
  )
69
69
  end
70
70
 
71
- let(:snippet1) { Youtube::Transcript::Rb::TranscriptSnippet.new(text: "Hello", start: 0.0, duration: 1.5) }
72
- let(:snippet2) { Youtube::Transcript::Rb::TranscriptSnippet.new(text: "World", start: 1.5, duration: 2.0) }
71
+ let(:snippet1) { YoutubeRb::Transcript::TranscriptSnippet.new(text: "Hello", start: 0.0, duration: 1.5) }
72
+ let(:snippet2) { YoutubeRb::Transcript::TranscriptSnippet.new(text: "World", start: 1.5, duration: 2.0) }
73
73
 
74
74
  describe "#initialize" do
75
75
  it "sets the video_id" do
@@ -214,12 +214,12 @@ RSpec.describe Youtube::Transcript::Rb do
214
214
  end
215
215
  end
216
216
 
217
- describe Youtube::Transcript::Rb::Transcript do
217
+ describe YoutubeRb::Transcript::TranscriptMetadata do
218
218
  let(:http_client) { double("Faraday::Connection") }
219
219
  let(:translation_languages) do
220
220
  [
221
- Youtube::Transcript::Rb::TranslationLanguage.new(language: "Spanish", language_code: "es"),
222
- Youtube::Transcript::Rb::TranslationLanguage.new(language: "French", language_code: "fr")
221
+ YoutubeRb::Transcript::TranslationLanguage.new(language: "Spanish", language_code: "es"),
222
+ YoutubeRb::Transcript::TranslationLanguage.new(language: "French", language_code: "fr")
223
223
  ]
224
224
  end
225
225
 
@@ -295,13 +295,13 @@ RSpec.describe Youtube::Transcript::Rb do
295
295
  it "raises NotTranslatable when not translatable" do
296
296
  expect {
297
297
  transcript_without_translations.translate("es")
298
- }.to raise_error(Youtube::Transcript::Rb::NotTranslatable)
298
+ }.to raise_error(YoutubeRb::Transcript::NotTranslatable)
299
299
  end
300
300
 
301
301
  it "raises TranslationLanguageNotAvailable for unavailable language" do
302
302
  expect {
303
303
  transcript.translate("de")
304
- }.to raise_error(Youtube::Transcript::Rb::TranslationLanguageNotAvailable)
304
+ }.to raise_error(YoutubeRb::Transcript::TranslationLanguageNotAvailable)
305
305
  end
306
306
 
307
307
  it "returns a new Transcript for available language" do
@@ -347,7 +347,7 @@ RSpec.describe Youtube::Transcript::Rb do
347
347
 
348
348
  it "returns a FetchedTranscript" do
349
349
  result = transcript.fetch
350
- expect(result).to be_a(Youtube::Transcript::Rb::FetchedTranscript)
350
+ expect(result).to be_a(YoutubeRb::Transcript::FetchedTranscript)
351
351
  end
352
352
 
353
353
  it "parses the transcript snippets" do
@@ -376,18 +376,18 @@ RSpec.describe Youtube::Transcript::Rb do
376
376
  translation_languages: []
377
377
  )
378
378
 
379
- expect { po_transcript.fetch }.to raise_error(Youtube::Transcript::Rb::PoTokenRequired)
379
+ expect { po_transcript.fetch }.to raise_error(YoutubeRb::Transcript::PoTokenRequired)
380
380
  end
381
381
 
382
382
  context "when HTTP error occurs" do
383
383
  it "raises IpBlocked for 429 status" do
384
384
  allow(http_client).to receive(:get).and_return(double("Response", status: 429, body: ""))
385
- expect { transcript.fetch }.to raise_error(Youtube::Transcript::Rb::IpBlocked)
385
+ expect { transcript.fetch }.to raise_error(YoutubeRb::Transcript::IpBlocked)
386
386
  end
387
387
 
388
388
  it "raises YouTubeRequestFailed for 4xx/5xx status" do
389
389
  allow(http_client).to receive(:get).and_return(double("Response", status: 500, body: ""))
390
- expect { transcript.fetch }.to raise_error(Youtube::Transcript::Rb::YouTubeRequestFailed)
390
+ expect { transcript.fetch }.to raise_error(YoutubeRb::Transcript::YouTubeRequestFailed)
391
391
  end
392
392
  end
393
393
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: youtube-transcript-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jeff.dean
@@ -71,17 +71,17 @@ files:
71
71
  - PLAN.md
72
72
  - README.md
73
73
  - Rakefile
74
- - lib/youtube/transcript/rb.rb
75
- - lib/youtube/transcript/rb/api.rb
76
- - lib/youtube/transcript/rb/errors.rb
77
- - lib/youtube/transcript/rb/formatters.rb
78
- - lib/youtube/transcript/rb/settings.rb
79
- - lib/youtube/transcript/rb/transcript.rb
80
- - lib/youtube/transcript/rb/transcript_list.rb
81
- - lib/youtube/transcript/rb/transcript_list_fetcher.rb
82
- - lib/youtube/transcript/rb/transcript_parser.rb
83
- - lib/youtube/transcript/rb/version.rb
84
- - sig/youtube/transcript/rb.rbs
74
+ - lib/youtube_rb/transcript.rb
75
+ - lib/youtube_rb/transcript/api.rb
76
+ - lib/youtube_rb/transcript/errors.rb
77
+ - lib/youtube_rb/transcript/formatters.rb
78
+ - lib/youtube_rb/transcript/settings.rb
79
+ - lib/youtube_rb/transcript/transcript.rb
80
+ - lib/youtube_rb/transcript/transcript_list.rb
81
+ - lib/youtube_rb/transcript/transcript_list_fetcher.rb
82
+ - lib/youtube_rb/transcript/transcript_parser.rb
83
+ - lib/youtube_rb/transcript/version.rb
84
+ - sig/youtube_rb/transcript.rbs
85
85
  - spec/api_spec.rb
86
86
  - spec/errors_spec.rb
87
87
  - spec/formatters_spec.rb
@@ -1,150 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "faraday"
4
- require "faraday/follow_redirects"
5
-
6
- module Youtube
7
- module Transcript
8
- module Rb
9
- # Main entry point for fetching YouTube transcripts.
10
- # This class provides a simple API for retrieving transcripts from YouTube videos.
11
- #
12
- # @example Basic usage
13
- # api = Youtube::Transcript::Rb::YouTubeTranscriptApi.new
14
- # transcript = api.fetch("dQw4w9WgXcQ")
15
- # transcript.each { |snippet| puts snippet.text }
16
- #
17
- # @example With language preference
18
- # api = Youtube::Transcript::Rb::YouTubeTranscriptApi.new
19
- # transcript = api.fetch("dQw4w9WgXcQ", languages: ["es", "en"])
20
- #
21
- # @example Listing available transcripts
22
- # api = Youtube::Transcript::Rb::YouTubeTranscriptApi.new
23
- # transcript_list = api.list("dQw4w9WgXcQ")
24
- # transcript_list.each { |t| puts t }
25
- #
26
- class YouTubeTranscriptApi
27
- # Default timeout for HTTP requests in seconds
28
- DEFAULT_TIMEOUT = 30
29
-
30
- # @param http_client [Faraday::Connection, nil] Custom HTTP client (optional)
31
- # @param proxy_config [Object, nil] Proxy configuration (optional)
32
- def initialize(http_client: nil, proxy_config: nil)
33
- @http_client = http_client || build_default_http_client
34
- @proxy_config = proxy_config
35
- @fetcher = TranscriptListFetcher.new(
36
- http_client: @http_client,
37
- proxy_config: @proxy_config
38
- )
39
- end
40
-
41
- # Fetch a transcript for a video.
42
- # This is a convenience method that combines `list` and `find_transcript`.
43
- #
44
- # @param video_id [String] The YouTube video ID
45
- # @param languages [Array<String>] Language codes in order of preference (default: ["en"])
46
- # @param preserve_formatting [Boolean] Whether to preserve HTML formatting (default: false)
47
- # @return [FetchedTranscript] The fetched transcript
48
- # @raise [NoTranscriptFound] If no transcript matches the requested languages
49
- # @raise [TranscriptsDisabled] If transcripts are disabled for the video
50
- # @raise [VideoUnavailable] If the video is not available
51
- #
52
- # @example
53
- # api = YouTubeTranscriptApi.new
54
- # transcript = api.fetch("dQw4w9WgXcQ", languages: ["en", "es"])
55
- # puts transcript.first.text
56
- #
57
- def fetch(video_id, languages: ["en"], preserve_formatting: false)
58
- list(video_id)
59
- .find_transcript(languages)
60
- .fetch(preserve_formatting: preserve_formatting)
61
- end
62
-
63
- # List all available transcripts for a video.
64
- #
65
- # @param video_id [String] The YouTube video ID
66
- # @return [TranscriptList] A list of available transcripts
67
- # @raise [TranscriptsDisabled] If transcripts are disabled for the video
68
- # @raise [VideoUnavailable] If the video is not available
69
- #
70
- # @example
71
- # api = YouTubeTranscriptApi.new
72
- # transcript_list = api.list("dQw4w9WgXcQ")
73
- #
74
- # # Find a specific transcript
75
- # transcript = transcript_list.find_transcript(["en"])
76
- #
77
- # # Or iterate over all available transcripts
78
- # transcript_list.each do |transcript|
79
- # puts "#{transcript.language_code}: #{transcript.language}"
80
- # end
81
- #
82
- def list(video_id)
83
- @fetcher.fetch(video_id)
84
- end
85
-
86
- # Fetch transcripts for multiple videos.
87
- #
88
- # @param video_ids [Array<String>] Array of YouTube video IDs
89
- # @param languages [Array<String>] Language codes in order of preference (default: ["en"])
90
- # @param preserve_formatting [Boolean] Whether to preserve HTML formatting (default: false)
91
- # @param continue_on_error [Boolean] Whether to continue if a video fails (default: false)
92
- # @yield [video_id, result] Block called for each video with either transcript or error
93
- # @yieldparam video_id [String] The video ID being processed
94
- # @yieldparam result [FetchedTranscript, StandardError] The transcript or error
95
- # @return [Hash<String, FetchedTranscript>] Hash mapping video IDs to transcripts
96
- # @raise [CouldNotRetrieveTranscript] If any video fails and continue_on_error is false
97
- #
98
- # @example Fetch multiple videos
99
- # api = YouTubeTranscriptApi.new
100
- # transcripts = api.fetch_all(["video1", "video2", "video3"])
101
- # transcripts.each { |id, t| puts "#{id}: #{t.length} snippets" }
102
- #
103
- # @example With error handling
104
- # api = YouTubeTranscriptApi.new
105
- # api.fetch_all(["video1", "video2"], continue_on_error: true) do |video_id, result|
106
- # if result.is_a?(StandardError)
107
- # puts "Error for #{video_id}: #{result.message}"
108
- # else
109
- # puts "Got #{result.length} snippets for #{video_id}"
110
- # end
111
- # end
112
- #
113
- def fetch_all(video_ids, languages: ["en"], preserve_formatting: false, continue_on_error: false)
114
- results = {}
115
-
116
- video_ids.each do |video_id|
117
- begin
118
- transcript = fetch(video_id, languages: languages, preserve_formatting: preserve_formatting)
119
- results[video_id] = transcript
120
- yield(video_id, transcript) if block_given?
121
- rescue CouldNotRetrieveTranscript => e
122
- if continue_on_error
123
- yield(video_id, e) if block_given?
124
- else
125
- raise
126
- end
127
- end
128
- end
129
-
130
- results
131
- end
132
-
133
- private
134
-
135
- # Build the default Faraday HTTP client
136
- #
137
- # @return [Faraday::Connection] The configured HTTP client
138
- def build_default_http_client
139
- Faraday.new do |conn|
140
- conn.options.timeout = DEFAULT_TIMEOUT
141
- conn.options.open_timeout = DEFAULT_TIMEOUT
142
- conn.request :url_encoded
143
- conn.response :follow_redirects
144
- conn.adapter Faraday.default_adapter
145
- end
146
- end
147
- end
148
- end
149
- end
150
- end
@@ -1,217 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Youtube
4
- module Transcript
5
- module Rb
6
- # Base error class for all YouTube Transcript errors
7
- class Error < StandardError; end
8
-
9
- # Raised when a transcript could not be retrieved
10
- class CouldNotRetrieveTranscript < Error
11
- WATCH_URL = "https://www.youtube.com/watch?v=%<video_id>s"
12
-
13
- # @return [String] the video ID that caused the error
14
- attr_reader :video_id
15
-
16
- # @param video_id [String] the YouTube video ID
17
- def initialize(video_id)
18
- @video_id = video_id
19
- super(build_error_message)
20
- end
21
-
22
- # @return [String] the cause of the error
23
- def cause_message
24
- self.class::CAUSE_MESSAGE
25
- end
26
-
27
- private
28
-
29
- def build_error_message
30
- video_url = format(WATCH_URL, video_id: @video_id)
31
- message = "\nCould not retrieve a transcript for the video #{video_url}!"
32
-
33
- if cause_message && !cause_message.empty?
34
- message += " This is most likely caused by:\n\n#{cause_message}"
35
- message += github_referral
36
- end
37
-
38
- message
39
- end
40
-
41
- def github_referral
42
- "\n\nIf you are sure that the described cause is not responsible for this error " \
43
- "and that a transcript should be retrievable, please create an issue at " \
44
- "https://github.com/jdepoix/youtube-transcript-api/issues. " \
45
- "Please add which version of youtube_transcript_api you are using " \
46
- "and provide the information needed to replicate the error. " \
47
- "Also make sure that there are no open issues which already describe your problem!"
48
- end
49
- end
50
-
51
- # Raised when YouTube data cannot be parsed
52
- class YouTubeDataUnparsable < CouldNotRetrieveTranscript
53
- CAUSE_MESSAGE = "The data required to fetch the transcript is not parsable. This should " \
54
- "not happen, please open an issue (make sure to include the video ID)!"
55
- end
56
-
57
- # Raised when a request to YouTube fails
58
- class YouTubeRequestFailed < CouldNotRetrieveTranscript
59
- CAUSE_MESSAGE = "Request to YouTube failed: %<reason>s"
60
-
61
- # @return [String] the reason for the failure
62
- attr_reader :reason
63
-
64
- # @param video_id [String] the YouTube video ID
65
- # @param http_error [StandardError] the HTTP error that occurred
66
- def initialize(video_id, http_error)
67
- @reason = http_error.to_s
68
- super(video_id)
69
- end
70
-
71
- def cause_message
72
- format(CAUSE_MESSAGE, reason: @reason)
73
- end
74
- end
75
-
76
- # Raised when a video is unplayable
77
- class VideoUnplayable < CouldNotRetrieveTranscript
78
- CAUSE_MESSAGE = "The video is unplayable for the following reason: %<reason>s"
79
-
80
- # @return [String, nil] the reason the video is unplayable
81
- attr_reader :reason
82
-
83
- # @return [Array<String>] additional sub-reasons
84
- attr_reader :sub_reasons
85
-
86
- # @param video_id [String] the YouTube video ID
87
- # @param reason [String, nil] the reason the video is unplayable
88
- # @param sub_reasons [Array<String>] additional details
89
- def initialize(video_id, reason = nil, sub_reasons = [])
90
- @reason = reason
91
- @sub_reasons = sub_reasons
92
- super(video_id)
93
- end
94
-
95
- def cause_message
96
- reason_text = @reason || "No reason specified!"
97
-
98
- if @sub_reasons.any?
99
- sub_reasons_text = @sub_reasons.map { |r| " - #{r}" }.join("\n")
100
- reason_text = "#{reason_text}\n\nAdditional Details:\n#{sub_reasons_text}"
101
- end
102
-
103
- format(CAUSE_MESSAGE, reason: reason_text)
104
- end
105
- end
106
-
107
- # Raised when a video is unavailable
108
- class VideoUnavailable < CouldNotRetrieveTranscript
109
- CAUSE_MESSAGE = "The video is no longer available"
110
- end
111
-
112
- # Raised when an invalid video ID is provided
113
- class InvalidVideoId < CouldNotRetrieveTranscript
114
- CAUSE_MESSAGE = "You provided an invalid video id. Make sure you are using the video id and NOT the url!\n\n" \
115
- 'Do NOT run: `Youtube::Transcript::Rb.fetch("https://www.youtube.com/watch?v=1234")`' \
116
- "\n" \
117
- 'Instead run: `Youtube::Transcript::Rb.fetch("1234")`'
118
- end
119
-
120
- # Raised when YouTube blocks the request
121
- class RequestBlocked < CouldNotRetrieveTranscript
122
- BASE_CAUSE_MESSAGE = "YouTube is blocking requests from your IP. This usually is due to one of the " \
123
- "following reasons:\n" \
124
- "- You have done too many requests and your IP has been blocked by YouTube\n" \
125
- "- You are doing requests from an IP belonging to a cloud provider (like AWS, " \
126
- "Google Cloud Platform, Azure, etc.). Unfortunately, most IPs from cloud " \
127
- "providers are blocked by YouTube.\n\n"
128
-
129
- CAUSE_MESSAGE = "#{BASE_CAUSE_MESSAGE}" \
130
- "There are two things you can do to work around this:\n" \
131
- "1. Use proxies to hide your IP address.\n" \
132
- "2. (NOT RECOMMENDED) If you authenticate your requests using cookies, you " \
133
- "will be able to continue doing requests for a while. However, YouTube will " \
134
- "eventually permanently ban the account that you have used to authenticate " \
135
- "with! So only do this if you don't mind your account being banned!"
136
- end
137
-
138
- # Raised when YouTube blocks the IP specifically
139
- class IpBlocked < RequestBlocked
140
- CAUSE_MESSAGE = "#{RequestBlocked::BASE_CAUSE_MESSAGE}" \
141
- "Ways to work around this are using proxies or rotating residential IPs."
142
- end
143
-
144
- # Raised when too many requests are made (HTTP 429)
145
- class TooManyRequests < CouldNotRetrieveTranscript
146
- CAUSE_MESSAGE = "YouTube is rate limiting your requests. Please wait before making more requests."
147
- end
148
-
149
- # Raised when transcripts are disabled for a video
150
- class TranscriptsDisabled < CouldNotRetrieveTranscript
151
- CAUSE_MESSAGE = "Subtitles are disabled for this video"
152
- end
153
-
154
- # Raised when a video is age restricted
155
- class AgeRestricted < CouldNotRetrieveTranscript
156
- CAUSE_MESSAGE = "This video is age-restricted. Therefore, you are unable to retrieve " \
157
- "transcripts for it without authenticating yourself.\n\n" \
158
- "Unfortunately, Cookie Authentication is temporarily unsupported, " \
159
- "as recent changes in YouTube's API broke the previous implementation."
160
- end
161
-
162
- # Raised when a transcript is not translatable
163
- class NotTranslatable < CouldNotRetrieveTranscript
164
- CAUSE_MESSAGE = "The requested language is not translatable"
165
- end
166
-
167
- # Raised when the requested translation language is not available
168
- class TranslationLanguageNotAvailable < CouldNotRetrieveTranscript
169
- CAUSE_MESSAGE = "The requested translation language is not available"
170
- end
171
-
172
- # Raised when consent cookie creation fails
173
- class FailedToCreateConsentCookie < CouldNotRetrieveTranscript
174
- CAUSE_MESSAGE = "Failed to automatically give consent to saving cookies"
175
- end
176
-
177
- # Raised when no transcript is found for the requested languages
178
- class NoTranscriptFound < CouldNotRetrieveTranscript
179
- CAUSE_MESSAGE = "No transcripts were found for any of the requested language codes: %<requested_language_codes>s\n\n%<transcript_data>s"
180
-
181
- # @return [Array<String>] the requested language codes
182
- attr_reader :requested_language_codes
183
-
184
- # @return [Object] the transcript data (TranscriptList)
185
- attr_reader :transcript_data
186
-
187
- # @param video_id [String] the YouTube video ID
188
- # @param requested_language_codes [Array<String>] the language codes that were requested
189
- # @param transcript_data [Object] the TranscriptList object with available transcripts
190
- def initialize(video_id, requested_language_codes, transcript_data)
191
- @requested_language_codes = requested_language_codes
192
- @transcript_data = transcript_data
193
- super(video_id)
194
- end
195
-
196
- def cause_message
197
- format(
198
- CAUSE_MESSAGE,
199
- requested_language_codes: @requested_language_codes.inspect,
200
- transcript_data: @transcript_data.to_s
201
- )
202
- end
203
- end
204
-
205
- # Raised when no transcripts are available for a video
206
- class NoTranscriptAvailable < CouldNotRetrieveTranscript
207
- CAUSE_MESSAGE = "No transcripts are available for this video"
208
- end
209
-
210
- # Raised when a PO token is required to fetch the transcript
211
- class PoTokenRequired < CouldNotRetrieveTranscript
212
- CAUSE_MESSAGE = "The requested video cannot be retrieved without a PO Token. " \
213
- "If this happens, please open a GitHub issue!"
214
- end
215
- end
216
- end
217
- end