見出し画像

GrokさんとVibeコーディングしてYouTubeから字幕をwebvtt出力させてみた件

YouTube動画をGrokに要約させたり、こんな話してる箇所とかありますか?とか聞くのがとても便利でトランスクリプトを取得することが増えたのですが、これを簡単にしたいということでGrokにPythonスクリプトを作らせてみました。

でもテキスト起こしが欲しいだけならば、皆さんは普通にウェブサービスを使ったほうがいいかと思いますw

どれがいいとかまでは知りません。

私はGrokに渡すTokenを最小にしたいなと思ったのでvttで出力させてから、これに前処理したり必要最小限にしてからGrokに内容を要約させたりという使い方を考えています。spaCyでぶちぎりの文章を復元してGrokの用語の認識精度を上げたりも重要ですね。

ちょっと前まではrumbleのビデオには字幕がなかったのでwhisperxで自前で字幕作ってさらには話して推定までして、エラー訂正して、そっから日本語訳つくったりしていましたが、Grokに要約させるならvtt作れたらまあ十分ですね。Youtubeなら字幕が勝手にできている場合が多いのでwhisperいりません。

いやー、結構面倒くさいプログラミングについてはGrokさんに外注させてWTM日本語訳チャネルのBotの開発も楽をするようになりましたが、Grok3の書くコードはなかなか素晴らしいのでちょっとした手直しでちゃんと動作させられます。こういうのを最近はVibeコーディングと言うようです。

バイブコーディングAIに依存したプログラミング手法で、人は解きたい問題を、コーディングに特化した大規模言語モデル(LLM)へのプロンプトとして自然言語で記述する。LLMによるソフトウェアの生成が可能となったことで、プログラマの役割は手作業によるコーディングから、AIがソースコードを生成する際のガイドと生成したコードのテスト・改良へと変化してきている[1][2][3]。そのためバイブコーディングの支持者は、これまでソフトウェア工学で必要とされてきた広範なトレーニング経験やスキルを持ち合わせていない素人のプログラマであってもソフトウェアを作成できると主張している[4]。この用語は2025年2月にアンドレイ・カーパシーによって提唱され[5][6][7][8]、翌月にはウェブスター辞典の「スラングとトレンド」に名詞として掲載された[9]

ウィキペディア

とくにseleniumとかBeautifulSoupとかを使ったややこしいコードは手作業で書くのは苦痛ですので、かるーい気持ちで始めたこの企画もバグ取りにちょいと苦労しましたが完成させることができました。

対象がYouTubeというややこしいUIや広告をを掻い潜る必要があったために手こずった部分があるのですが、もうちょっと単純なページならもっとあっさりできたと思います。


使い方

プログラムは一番下に置いておきますが、使い方はこんなです。

python get_vtt_from_youtube.py https://youtu.be/aa6-rEO4ghY

基本的にはUbuntu系列のディストロなら動くと思いますがChromeかChromium、そしてChromeDriverが必要です。

# Chromeをインストール
sudo apt update
sudo apt install -y wget unzip
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo apt-get install -f

# ChromeDriverをインストール
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+')
wget https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_VERSION -O /tmp/chromedriver_version
wget https://chromedriver.storage.googleapis.com/$(cat /tmp/chromedriver_version)/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin/
sudo chmod +x /usr/local/bin/chromedriver

あとは適当にvenvを作ってライブラリをインスコしておいてください。

pip install selenium beautifulsoup4 requests webvtt-py

GrokさんとのVibeコーディング

基本的には要望を伝えて、

いまくいってない部分のエラーを貼ってあげたり、状況を説明してあげると書き直してくれるので、その繰り返し。たまに自分でデバックして助けて上げたりもしました。


出力の例

このビデオのトランスクリプトを作ってみました。

追記) vttじゃなくwebvttにフォーマット変更しました。

WEBVTT

00:00:00.000 --> 00:00:02.000
so is it the art of the deal to just

00:00:03.000 --> 00:00:05.000
make a bunch of demands and then to back

00:00:05.000 --> 00:00:07.000
down from them and flip-flop every other

00:00:07.000 --> 00:00:09.000
day like a flippity floppity fish or is

00:00:09.000 --> 00:00:11.000
this yet another masterful 10D chess

00:00:12.000 --> 00:00:14.000
move in which President Trump has

00:00:14.000 --> 00:00:16.000
excluded tariffs essentially eliminating

00:00:17.000 --> 00:00:19.000
most of them from Chinese electronics

00:00:19.000 --> 00:00:21.000
phones laptops computer chips i mean

00:00:22.000 --> 00:00:24.000
what's even the point of tariffs then to

00:00:24.000 --> 00:00:26.000
bring manufacturing of clothing socks

00:00:27.000 --> 00:00:29.000
sweaters and shoes back to the US and so

00:00:30.000 --> 00:00:32.000
in a massive turn of events and arguably

00:00:32.000 --> 00:00:34.000
some might even say a massive defeat and

00:00:34.000 --> 00:00:36.000
a stunning loss of leverage for United

00:00:37.000 --> 00:00:39.000
States in negotiations in the coming

00:00:38.000 --> 00:00:40.000
weeks and months ahead the US has

00:00:41.000 --> 00:00:43.000
decided to just exclude basically

00:00:43.000 --> 00:00:45.000
everything from the reciprocal tariffs

00:00:45.000 --> 00:00:47.000
from China i mean we're talking about

00:00:48.000 --> 00:00:50.000
laptops smartphones chips computer parts

00:00:50.000 --> 00:00:52.000
flash memory drives SSDs media recording

00:00:53.000 --> 00:00:55.000
sound equipment and on this news the

00:00:55.000 --> 00:00:57.000
crypto markets have rallied with Bitcoin

00:00:57.000 --> 00:00:59.000
nearing 85,000 and this could be a buy

00:01:00.000 --> 00:01:02.000
signal this could actually be a bottom

00:01:02.000 --> 00:01:04.000
as we're seeing a pivot in the direction

00:01:04.000 --> 00:01:06.000
of the US government and we're going to

00:01:06.000 --> 00:01:08.000
see more deescalation ethereum is

00:01:08.000 --> 00:01:10.000
running up 4.9% the past 24 hours and

00:01:12.000 --> 00:01:14.000
this is something we need to be a bit

00:01:14.000 --> 00:01:16.000
careful about here because it seems to

00:01:15.000 --> 00:01:17.000
be running a little bit ahead of itself

00:01:17.000 --> 00:01:19.000
here and actually this could represent

00:01:19.000 --> 00:01:21.000
retail hype anytime Ethereum starts

00:01:21.000 --> 00:01:23.000
running ahead of Bitcoin I have to ask

00:01:23.000 --> 00:01:25.000
myself what are we fleeing to is it a

00:01:25.000 --> 00:01:27.000
flight to safety and hard assets like

00:01:27.000 --> 00:01:29.000
Bitcoin or is industry manufacturing is

00:01:31.000 --> 00:01:33.000
commercialization and growth back are we

00:01:34.000 --> 00:01:36.000
out of the recession in that case maybe

00:01:36.000 --> 00:01:38.000
Ethereum could run faster but if we

00:01:38.000 --> 00:01:40.000
check ourselves here this is where we

00:01:40.000 --> 00:01:42.000
need to be careful about just jumping

00:01:42.000 --> 00:01:44.000
back into these markets the White House

00:01:44.000 --> 00:01:46.000
deputy of staff clarifies that the

00:01:46.000 --> 00:01:48.000
original 20% tariffs are still on for

00:01:49.000 --> 00:01:51.000
China so this is where I'm thinking that

00:01:52.000 --> 00:01:54.000
a lot of the retail crypto traders may

00:01:54.000 --> 00:01:56.000
be jumping ahead of the train here

00:01:56.000 --> 00:01:58.000
you've got a lot of crypto djen traders

00:01:58.000 --> 00:02:00.000
on 100x leverage these ETH maxis trying

00:02:00.000 --> 00:02:02.000
to make their bags back because they've

00:02:02.000 --> 00:02:04.000
lost so much they're desperate out here

00:02:04.000 --> 00:02:06.000
and you know the smart money is going to

00:02:06.000 --> 00:02:08.000
know the tariff thing isn't entirely

00:02:08.000 --> 00:02:10.000
over you've still got 20% and this whole

00:02:10.000 --> 00:02:12.000
issue still needs to be resolved not to

00:02:12.000 --> 00:02:14.000
mention on Friday Apple had already run

00:02:15.000 --> 00:02:17.000
up 4% so some of this is definitely

00:02:18.000 --> 00:02:20.000
priced in already the market was

00:02:19.000 --> 00:02:21.000
expecting a deescalation nvidia was up

00:02:22.000 --> 00:02:24.000
3% on Friday so in my view we can't

00:02:25.000 --> 00:02:27.000
necessarily just expect out season to

00:02:27.000 --> 00:02:29.000
come back and to jump back into tech

00:02:29.000 --> 00:02:31.000
stocks and expect growth to come back to

00:02:31.000 --> 00:02:33.000
the US because there's still a lot of

00:02:33.000 --> 00:02:35.000
recessionary risks in play here you know

00:02:36.000 --> 00:02:38.000
the AI bubble has been popping deep sea

00:02:38.000 --> 00:02:40.000
came before the tariffs and as far as

00:02:40.000 --> 00:02:42.000
tariffs go we just lost a lot of

00:02:43.000 --> 00:02:45.000
negotiation ground and basically all of

00:02:45.000 --> 00:02:47.000
our leverage here right we're going to

00:02:47.000 --> 00:02:49.000
have negotiations with 75 plus countries

00:02:49.000 --> 00:02:51.000
as I recall and all of these countries

00:02:52.000 --> 00:02:54.000
are probably going to be asking for the

00:02:54.000 --> 00:02:56.000
same exclusions and exemptions that

00:02:56.000 --> 00:02:58.000
they're saying we're making for these

00:02:57.000 --> 00:02:59.000
big tech companies right they see that

00:02:59.000 --> 00:03:01.000
we're willing to back down we can back

00:03:01.000 --> 00:03:03.000
down i mean we're just flip-flopping

00:03:03.000 --> 00:03:05.000
back and forth and the weird thing is

00:03:05.000 --> 00:03:07.000
these tariff exemptions now

00:03:06.000 --> 00:03:08.000
disproportionately benefit big tech like

00:03:08.000 --> 00:03:10.000
Apple Nvidia Google you know we saw the

00:03:11.000 --> 00:03:13.000
big tech CEOs having their million-doll

00:03:13.000 --> 00:03:15.000
lunches with President Trump earlier did

00:03:16.000 --> 00:03:18.000
that play a part in this the optics

00:03:18.000 --> 00:03:20.000
aren't looking so good while all the

00:03:19.000 --> 00:03:21.000
meanwhile lower income Americans may be

00:03:22.000 --> 00:03:24.000
suffering more because they need to buy

00:03:24.000 --> 00:03:26.000
the low tax stuff and the small

00:03:25.000 --> 00:03:27.000
businesses may be hurt now well why

00:03:28.000 --> 00:03:30.000
don't they get exclusions too they're

00:03:29.000 --> 00:03:31.000
going to be asking for that and then car

00:03:31.000 --> 00:03:33.000
parts are also notably not exempt well

00:03:34.000 --> 00:03:36.000
what about Tesla and Elon Musk we've got

00:03:36.000 --> 00:03:38.000
to help them out too here so let's add

00:03:38.000 --> 00:03:40.000
an exemption for Tesla here too right we

00:03:40.000 --> 00:03:42.000
should do that and Tesla has been facing

00:03:43.000 --> 00:03:45.000
issues they had to halt orders in China

00:03:46.000 --> 00:03:48.000
for the US imported models because of

00:03:48.000 --> 00:03:50.000
the reciprocal tariffs that Beijing

00:03:50.000 --> 00:03:52.000
imposed on America tesla had to quietly

00:03:52.000 --> 00:03:54.000
remove the order button from the Model S

00:03:54.000 --> 00:03:56.000
and Model X vehicles and some are

00:03:58.000 --> 00:04:00.000
saying history will remember that China

00:04:01.000 --> 00:04:03.000
stood up against American imperialism

00:04:03.000 --> 00:04:05.000
and

00:04:05.000 --> 00:04:07.000
coercions in this grand show where the

00:04:07.000 --> 00:04:09.000
US waged war on the whole entire world

00:04:10.000 --> 00:04:12.000
and China said I got this i got this and

00:04:15.000 --> 00:04:17.000
they got it and the world has China to

00:04:17.000 --> 00:04:19.000
thank for saving their economies

00:04:19.000 --> 00:04:21.000
arguably the Chinese embassy stated give

00:04:22.000 --> 00:04:24.000
the bully an inch and he will take a

00:04:24.000 --> 00:04:26.000
mile well China did not back down and

00:04:26.000 --> 00:04:28.000
they gave not a single inch matching the

00:04:28.000 --> 00:04:30.000
US tariffs one for one up until 125% and

00:04:32.000 --> 00:04:34.000
with that China stating this is the end

00:04:34.000 --> 00:04:36.000
of escalations even if the US imposes

00:04:36.000 --> 00:04:38.000
higher tariffs it will no longer make

00:04:38.000 --> 00:04:40.000
economic sense and ultimately go down as

00:04:40.000 --> 00:04:42.000
a joke in world economic history is it a

00:04:43.000 --> 00:04:45.000
joke or is it the art of the deal i mean

00:04:46.000 --> 00:04:48.000
this could yet be a 4D 5D 100D chess

00:04:49.000 --> 00:04:51.000
move but the US could be in serious

00:04:52.000 --> 00:04:54.000
trouble here actually i mean we may have

00:04:56.000 --> 00:04:58.000
screwed ourselves here we're bankrupt

00:04:59.000 --> 00:05:01.000
guys we are going bankrupt fast here our

00:05:01.000 --> 00:05:03.000
debt is going parabolic to the moon at

00:05:04.000 --> 00:05:06.000
nearly 37 trillion at 37 trillion in

00:05:08.000 --> 00:05:10.000
debt with an interest rate of around 4%

00:05:10.000 --> 00:05:12.000
that we're paying we need about $1.5

00:05:13.000 --> 00:05:15.000
trillion in gross revenues just to pay

00:05:16.000 --> 00:05:18.000
off this debt and these tariffs was

00:05:18.000 --> 00:05:20.000
really the last chance we had at this

00:05:21.000 --> 00:05:23.000
the plan was to get Doge to save one

00:05:23.000 --> 00:05:25.000
trillion and then the tariffs would make

00:05:25.000 --> 00:05:27.000
the other trillion so we get two

00:05:26.000 --> 00:05:28.000
trillion in profit each year then we

00:05:29.000 --> 00:05:31.000
could get the debt under control now we

00:05:32.000 --> 00:05:34.000
don't have a plan anymore for our debt

00:05:34.000 --> 00:05:36.000
you see Doge quietly lowered their

00:05:36.000 --> 00:05:38.000
estimates of savings from 1 trillion to

00:05:38.000 --> 00:05:40.000
just 150 billion and this is not going

00:05:41.000 --> 00:05:43.000
to be enough and at the same time our

00:05:43.000 --> 00:05:45.000
spending exceeded our savings at 154

00:05:47.000 --> 00:05:49.000
billion and so effectively we have saved

00:05:49.000 --> 00:05:51.000
nothing year to date and to make matters

00:05:52.000 --> 00:05:54.000
worse we've got a surprise announcement

00:05:54.000 --> 00:05:56.000
another $1 trillion in military defense

00:05:57.000 --> 00:05:59.000
spending well where are we getting the

00:05:59.000 --> 00:06:01.000
money for all this tariffs Doge or are

00:06:03.000 --> 00:06:05.000
we printing so we need to have an

00:06:05.000 --> 00:06:07.000
accurate gauge of the economy here are

00:06:07.000 --> 00:06:09.000
we euphoric at the time when Google just

00:06:09.000 --> 00:06:11.000
announced they're laying off hundreds of

00:06:11.000 --> 00:06:13.000
employees in the Android Pixel and

00:06:13.000 --> 00:06:15.000
Chrome teams and Microsoft is also

00:06:15.000 --> 00:06:17.000
considering additional layoffs in May on

00:06:18.000 --> 00:06:20.000
managers and non-coders this time and so

00:06:20.000 --> 00:06:22.000
the economy is not doing that great and

00:06:22.000 --> 00:06:24.000
the main story continues to be the

00:06:24.000 --> 00:06:26.000
dollar index how strong is the dollar

00:06:26.000 --> 00:06:28.000
here it cratered actually to 99.8 under

00:06:29.000 --> 00:06:31.000
100 the first time it's reached this

00:06:31.000 --> 00:06:33.000
level since maybe 3 years ago analysts

00:06:34.000 --> 00:06:36.000
that the question of a potential dollar

00:06:36.000 --> 00:06:38.000
confidence crisis has now been

00:06:38.000 --> 00:06:40.000
definitely answered we're experiencing

00:06:40.000 --> 00:06:42.000
one in full force the dollar collapse is

00:06:41.000 --> 00:06:43.000
working as a barometer of sell America

00:06:44.000 --> 00:06:46.000
and so maybe we don't have the cards

00:06:45.000 --> 00:06:47.000
here actually with our full transparency

00:06:48.000 --> 00:06:50.000
which is notable we've ended up showing

00:06:50.000 --> 00:06:52.000
everybody our cards and they know our

00:06:52.000 --> 00:06:54.000
intentions they know how to prepare for

00:06:54.000 --> 00:06:56.000
this now and they know that we don't

00:06:55.000 --> 00:06:57.000
have much leverage we just gave up a

00:06:57.000 --> 00:06:59.000
bunch of our leverage for free basically

00:06:59.000 --> 00:07:01.000
and this is pushing our allies and trade

00:07:01.000 --> 00:07:03.000
partners away into China's waiting arms

00:07:04.000 --> 00:07:06.000
so China is now stepping up efforts to

00:07:06.000 --> 00:07:08.000
diversify away from US markets promoting

00:07:09.000 --> 00:07:11.000
itself as a responsible trading partner

00:07:11.000 --> 00:07:13.000
china's President Xiinping recently went

00:07:13.000 --> 00:07:15.000
over to Spain to build more strategic

00:07:15.000 --> 00:07:17.000
resilient partnerships looks like they

00:07:17.000 --> 00:07:19.000
had a great time over there you've got

00:07:19.000 --> 00:07:21.000
President Xi heading to Vietnam Malaysia

00:07:21.000 --> 00:07:23.000
Cambodia they're talking with Saudi

00:07:23.000 --> 00:07:25.000
Arabia South Africa and now they're

00:07:25.000 --> 00:07:27.000
seeking British backing to defend

00:07:27.000 --> 00:07:29.000
international trade you've got France

00:07:29.000 --> 00:07:31.000
working alongside the European

00:07:31.000 --> 00:07:33.000
Commission in full unity with a clear

00:07:33.000 --> 00:07:35.000
goal to negotiate the removal of unfair

00:07:35.000 --> 00:07:37.000
tariffs and we have EU leaders planning

00:07:37.000 --> 00:07:39.000
a Beijing trip in July for summit with

00:07:40.000 --> 00:07:42.000
China's President Xi so the fundamental

00:07:42.000 --> 00:07:44.000
problem here is we showed everybody our

00:07:44.000 --> 00:07:46.000
cards and showed them we were willing to

00:07:46.000 --> 00:07:48.000
abuse our power as the global reserve

00:07:49.000 --> 00:07:51.000
currency the trade partner for all these

00:07:51.000 --> 00:07:53.000
countries and now they're preparing to

00:07:53.000 --> 00:07:55.000
exclude and bypass the United States and

00:07:56.000 --> 00:07:58.000
they're not going to be caught off guard

00:07:57.000 --> 00:07:59.000
again because they're not going to be

00:07:59.000 --> 00:08:01.000
fooled twice and every country now is

00:08:01.000 --> 00:08:03.000
rethinking any US technology products or

00:08:04.000 --> 00:08:06.000
services that they may be dependent on

00:08:06.000 --> 00:08:08.000
and you have the EU now also taking a

00:08:09.000 --> 00:08:11.000
look at possibly levying fines on

00:08:11.000 --> 00:08:13.000
American tech companies they are

00:08:13.000 --> 00:08:15.000
developing retaliatory measures an

00:08:15.000 --> 00:08:17.000
example being levying the advertising

00:08:18.000 --> 00:08:20.000
revenues of digital services so this is

00:08:20.000 --> 00:08:22.000
like essentially putting tariffs on

00:08:22.000 --> 00:08:24.000
Google Apple or X's ad revenues the head

00:08:25.000 --> 00:08:27.000
of the EU stated "It is a complete

00:08:28.000 --> 00:08:30.000
inflection point in global trade we will

00:08:30.000 --> 00:08:32.000
never go back to the status quo." And so

00:08:32.000 --> 00:08:34.000
you can imagine if we somehow extract

00:08:34.000 --> 00:08:36.000
and everybody's max extracting here

00:08:36.000 --> 00:08:38.000
let's say we extract $100 million from

00:08:39.000 --> 00:08:41.000
the EU they're going to extract $100

00:08:41.000 --> 00:08:43.000
million in retaliation from say Google

00:08:43.000 --> 00:08:45.000
Facebook and X or Apple or any of our

00:08:45.000 --> 00:08:47.000
digital services and technologies

00:08:47.000 --> 00:08:49.000
they're going to recuperate their cost

00:08:49.000 --> 00:08:51.000
one way or another and so really the

00:08:51.000 --> 00:08:53.000
inflection point is for big tech and

00:08:53.000 --> 00:08:55.000
we're also seeing the continued

00:08:54.000 --> 00:08:56.000
implosion of the AI bubble meta's AI

00:08:58.000 --> 00:09:00.000
research lab is reportedly dying a slow

00:09:00.000 --> 00:09:02.000
death some insiders are saying as the

00:09:02.000 --> 00:09:04.000
head of AI research announced her

00:09:04.000 --> 00:09:06.000
departure last week the timing of the

00:09:06.000 --> 00:09:08.000
resignation raised eyebrows you know

00:09:09.000 --> 00:09:11.000
people wondering was this just a

00:09:11.000 --> 00:09:13.000
personal thing or was there some

00:09:12.000 --> 00:09:14.000
critical fundamental issue with Meta

00:09:14.000 --> 00:09:16.000
Lama 4 models which rolled out in

00:09:16.000 --> 00:09:18.000
controversy drawing criticism from

00:09:19.000 --> 00:09:21.000
possibly inflated performance metrics

00:09:22.000 --> 00:09:24.000
and we're also seeing that I mean some

00:09:23.000 --> 00:09:25.000
tech CEOs are going to jail now over AI

00:09:26.000 --> 00:09:28.000
which was actually just manual human

00:09:28.000 --> 00:09:30.000
labor so they just had a bunch of people

00:09:30.000 --> 00:09:32.000
in the Philippines pretending to be AI

00:09:33.000 --> 00:09:35.000
going around acting like robots doing

00:09:35.000 --> 00:09:37.000
some virtual shopping for you and raised

00:09:37.000 --> 00:09:39.000
a couple million dollars based on that

00:09:39.000 --> 00:09:41.000
now the whole scheme is unwinding you've

00:09:42.000 --> 00:09:44.000
got Mirror Moradi from Open AI

00:09:44.000 --> 00:09:46.000
continuing to raise $2 billion seed

00:09:47.000 --> 00:09:49.000
round on essentially no product and no

00:09:49.000 --> 00:09:51.000
revenues to speak of emerging from

00:09:51.000 --> 00:09:53.000
stealth on nothing so the tech sector

00:09:54.000 --> 00:09:56.000
may still be in this AI bubble imploding

00:09:57.000 --> 00:09:59.000
in slow motion which is obuscated by the

00:10:00.000 --> 00:10:02.000
tariffs confusion but even without the

00:10:02.000 --> 00:10:04.000
tariffs we may still see this implosion

00:10:04.000 --> 00:10:06.000
happening and the dollar may continue to

00:10:06.000 --> 00:10:08.000
weaken now that it's been tested

00:10:09.000 --> 00:10:11.000
critical cracks are showing and it's

00:10:11.000 --> 00:10:13.000
been revealed that investors are fleeing

00:10:13.000 --> 00:10:15.000
not to the dollar as a safe haven

00:10:15.000 --> 00:10:17.000
anymore they're going to hard assets

00:10:16.000 --> 00:10:18.000
like gold or bitcoin now at 85500 and in

00:10:20.000 --> 00:10:22.000
my view we may still be in a recession

00:10:23.000 --> 00:10:25.000
right what are we building out here you

00:10:25.000 --> 00:10:27.000
know the AI robots thing is going to

00:10:27.000 --> 00:10:29.000
take another 10 20 years just to play

00:10:29.000 --> 00:10:31.000
out and chat GBT subscriptions cannot

00:10:32.000 --> 00:10:34.000
pay back billions of dollars hundreds of

00:10:34.000 --> 00:10:36.000
billions of dollars worth of investments

00:10:36.000 --> 00:10:38.000
right that's not going to recoup the

00:10:38.000 --> 00:10:40.000
costs let's take a look at the Bitcoin

00:10:40.000 --> 00:10:42.000
hash rate here it is skyrocketing to

00:10:42.000 --> 00:10:44.000
all-time highs and price follows hash

00:10:44.000 --> 00:10:46.000
rate look Look at the divergence here on

00:10:47.000 --> 00:10:49.000
the price versus the hash rate now if

00:10:49.000 --> 00:10:51.000
the price were to realign with hash rate

00:10:51.000 --> 00:10:53.000
which it inevitably does then we'd be at

00:10:53.000 --> 00:10:55.000
like over 100k now but this could be an

00:10:57.000 --> 00:10:59.000
opportune moment for you to buy the dip

00:10:59.000 --> 00:11:01.000
because there is a fundamental change in

00:11:02.000 --> 00:11:04.000
course where the tariff negotiations

00:11:04.000 --> 00:11:06.000
have stopped escalating and now we are

00:11:06.000 --> 00:11:08.000
in a deescalatory phase in which we may

00:11:09.000 --> 00:11:11.000
see more liquidity injections coming

00:11:11.000 --> 00:11:13.000
back flowing into the markets as we are

00:11:14.000 --> 00:11:16.000
deescalating and tariffs are starting to

00:11:16.000 --> 00:11:18.000
come down we've already reached max

00:11:18.000 --> 00:11:20.000
tariff we can't increase the tariffs

00:11:20.000 --> 00:11:22.000
anymore 500 1,000% and so with the

00:11:23.000 --> 00:11:25.000
liquidity starting to flow back into the

00:11:25.000 --> 00:11:27.000
markets the only question is which asset

00:11:27.000 --> 00:11:29.000
do you want to get into and if you're

00:11:29.000 --> 00:11:31.000
bearish on the economy kind of like I am

00:11:31.000 --> 00:11:33.000
and you think there's still a lot of

00:11:32.000 --> 00:11:34.000
counterparty risk to tech and the AI

00:11:34.000 --> 00:11:36.000
bubble then you may want to get into

00:11:36.000 --> 00:11:38.000
hard assets like say Bitcoin and the Fed

00:11:38.000 --> 00:11:40.000
has two choices it can either not print

00:11:41.000 --> 00:11:43.000
in which the economy either does well or

00:11:43.000 --> 00:11:45.000
does poorly in either case you probably

00:11:45.000 --> 00:11:47.000
want some hard assets or if the economy

00:11:47.000 --> 00:11:49.000
is really doing poorly then the Fed's

00:11:49.000 --> 00:11:51.000
going to be printing more you're going

00:11:50.000 --> 00:11:52.000
to still want hard assets and so we've

00:11:52.000 --> 00:11:54.000
kind of got this Fed put in place here

00:11:54.000 --> 00:11:56.000
they've already signal they're ready to

00:11:56.000 --> 00:11:58.000
step into the markets if necessary so

00:11:59.000 --> 00:12:01.000
they're willing to print and so with

00:12:01.000 --> 00:12:03.000
that hope you enjoyed the update let me

00:12:03.000 --> 00:12:05.000
know your market moves in the comments

00:12:04.000 --> 00:12:06.000
below i'll see you there personally I

00:12:07.000 --> 00:12:09.000
would like to see the US take more of a

00:12:09.000 --> 00:12:11.000
respectful stance against nations and

00:12:11.000 --> 00:12:13.000
workers and laborers people who are

00:12:13.000 --> 00:12:15.000
working hard to make our products goods

00:12:15.000 --> 00:12:17.000
and services and ship them into our

00:12:16.000 --> 00:12:18.000
countries and we owe them some basic

00:12:19.000 --> 00:12:21.000
respect for that i will leave you with a

00:12:21.000 --> 00:12:23.000
speech from President Xiinping chinese

00:12:23.000 --> 00:12:25.000
people have never bullied oppressed or

00:12:25.000 --> 00:12:27.000
subjugated the people of any other

00:12:26.000 --> 00:12:28.000
country and we never will we will also

00:12:28.000 --> 00:12:30.000
never allow any foreign force to bully

00:12:30.000 --> 00:12:32.000
oppress or subjugate us so that's it for

00:12:34.000 --> 00:12:36.000
now if you like the video give a like

00:12:35.000 --> 00:12:37.000
and subscribe see you in the next one

00:12:38.000 --> 00:12:40.000
[Applause]

00:12:41.000 --> 00:12:43.000
[Music]

00:12:42.000 --> 00:12:44.000
[Applause]

00:12:43.000 --> 00:12:45.000
[Music]

00:12:44.000 --> 00:12:46.000
[Applause]

00:12:46.000 --> 00:12:48.000
[Music]

00:12:50.000 --> 00:12:52.000
[Applause]

00:12:51.000 --> 00:12:53.000
[Music]


最終的なコード

import sys
import re
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import webvtt
import time

def extract_video_id(url):
    """YouTube URLから動画IDを抽出"""
    patterns = [
        r'(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?v=([^&]+)',
        r'(?:https?:\/\/)?youtu\.be\/([^?]+)'
    ]
    for pattern in patterns:
        match = re.match(pattern, url)
        if match:
            return match.group(1)
    raise ValueError("無効なYouTube URLです")

def extract_youtube_transcript_to_vtt(url, quiet=False):
    # Seleniumのオプション設定(Ubuntu向け)
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36")
    chrome_options.add_argument("--window-size=1920,1080")
    chrome_options.add_argument("--disable-blink-features=AutomationControlled")
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_argument("--disable-extensions")
    chrome_options.add_argument("--start-maximized")

    # WebDriverの初期化
    driver = webdriver.Chrome(options=chrome_options)
    
    try:
        # YouTubeページを開く
        driver.get(url)
        if not quiet:
            print("ページを読み込みました:", url)
        time.sleep(3)
        
        # 「Before you continue to YouTube」の「Reject all」ボタンを探す
        try:
            reject_all_button = WebDriverWait(driver, 15).until(
                EC.element_to_be_clickable((By.XPATH, '//button[contains(@class, "yt-spec-button-shape-next") and (contains(text(), "Reject") or contains(@aria-label, "Reject"))]'))
            )
            if not quiet:
                print("「Reject all」ボタンが見つかりました:", reject_all_button.get_attribute("outerHTML"))
            driver.execute_script("arguments[0].scrollIntoView(true);", reject_all_button)
            driver.execute_script("arguments[0].click();", reject_all_button)
            try:
                WebDriverWait(driver, 5).until(
                    EC.invisibility_of_element((By.TAG_NAME, "tp-yt-iron-overlay-backdrop"))
                )
                if not quiet:
                    print("オーバーレイが消えました")
            except:
                if not quiet:
                    print("オーバーレイの待機中にエラーが発生しましたが、続行します")
        except Exception as e:
            if not quiet:
                print("「Reject all」ボタンが見つからないか、クリックできませんでした:", e)
                print("ダイアログが表示されていない可能性があります。処理を続行します。")

        # 広告のスキップや閉じる処理
        for _ in range(2):
            try:
                skip_ad_button = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable((By.XPATH, '//button[contains(@class, "ytp-ad-skip-button") or contains(text(), "Skip")]'))
                )
                if not quiet:
                    print("広告の「スキップ」ボタンが見つかりました:", skip_ad_button.get_attribute("outerHTML"))
                driver.execute_script("arguments[0].click();", skip_ad_button)
                if not quiet:
                    print("広告をスキップしました")
                time.sleep(1)
            except:
                if not quiet:
                    print("広告の「スキップ」ボタンが見つかりませんでした。広告がないか、スキップ不要です。")
                break

        # 「...more」ボタンをクリック
        try:
            more_button = WebDriverWait(driver, 40).until(
                EC.element_to_be_clickable((By.XPATH, '//tp-yt-paper-button[@id="expand"]'))
            )
            if not quiet:
                print("「...more」ボタンが見つかりました:", more_button.get_attribute("outerHTML"))
            driver.execute_script("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", more_button)
            time.sleep(0.5)
            driver.execute_script("arguments[0].click();", more_button)
            time.sleep(2)
        except Exception as e:
            if not quiet:
                print("「...more」ボタンが見つからないか、クリックできませんでした:", e)
                driver.save_screenshot("more_button_error.png")
                with open("more_button_error.html", "w", encoding="utf-8") as f:
                    f.write(driver.page_source)
                print("ページのHTMLを more_button_error.html に、スクリーンショットを more_button_error.png に保存しました")
            return None, None

        # 「Show transcript」ボタンをクリック
        try:
            transcript_button = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, '//button[@aria-label="Show transcript"]'))
            )
            if not quiet:
                print("「Show transcript」ボタンが見つかりました:", transcript_button.get_attribute("outerHTML"))
            driver.execute_script("arguments[0].scrollIntoView(true);", transcript_button)
            driver.execute_script("arguments[0].click();", transcript_button)
            time.sleep(2)
        except Exception as e:
            if not quiet:
                print("「Show transcript」ボタンが見つからないか、クリックできませんでした:", e)
            return None, None

        # トランスクリプトコンテナがロードされるまで待機
        try:
            WebDriverWait(driver, 20).until(
                EC.presence_of_element_located((By.ID, 'body'))
            )
            if not quiet:
                print("トランスクリプトのコンテナ(<div id='body'>)がロードされました")
        except Exception as e:
            if not quiet:
                print("トランスクリプトコンテナの読み込みに失敗しました:", e)
                driver.save_screenshot("transcript_error.png")
                with open("transcript_error.html", "w", encoding="utf-8") as f:
                    f.write(driver.page_source)
                print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
            return None, None

        # トランスクリプトのセグメントコンテナがロードされるまで待機
        max_attempts = 3
        for attempt in range(max_attempts):
            try:
                WebDriverWait(driver, 40).until(
                    EC.presence_of_element_located((By.ID, 'segments-container'))
                )
                if not quiet:
                    print("トランスクリプトのセグメントコンテナ(<div id='segments-container'>)がロードされました")
                break
            except Exception as e:
                if not quiet:
                    print(f"試行 {attempt+1}/{max_attempts}: トランスクリプトセグメントコンテナの読み込みに失敗しました:", e)
                if attempt < max_attempts - 1:
                    if not quiet:
                        print("再試行します...")
                    time.sleep(5)
                    driver.execute_script("arguments[0].click();", transcript_button)
                else:
                    if not quiet:
                        print("最終試行でも失敗しました")
                        driver.save_screenshot("transcript_error.png")
                        with open("transcript_error.html", "w", encoding="utf-8") as f:
                            f.write(driver.page_source)
                        print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
                    return None, None

        # ページのHTMLを取得
        page_source = driver.page_source
        soup = BeautifulSoup(page_source, 'html.parser')

        # トランスクリプトのdiv要素を抽出
        transcript_div = soup.find('div', id='body', class_='style-scope ytd-transcript-search-panel-renderer')
        if not transcript_div:
            if not quiet:
                print("トランスクリプトのコンテナ(<div id='body' class='style-scope ytd-transcript-search-panel-renderer'>)が見つかりませんでした")
                driver.save_screenshot("transcript_error.png")
                with open("transcript_error.html", "w", encoding="utf-8") as f:
                    f.write(driver.page_source)
                print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
            return None, None

        # トランスクリプトコンテナの内容をログに記録
        if not quiet:
            print("トランスクリプトコンテナのHTML:", str(transcript_div)[:2000])

        # セグメントコンテナを取得
        segments_container = transcript_div.find('div', id='segments-container')
        if not segments_container:
            if not quiet:
                print("セグメントコンテナ(<div id='segments-container'>)が見つかりませんでした")
                driver.save_screenshot("transcript_error.png")
                with open("transcript_error.html", "w", encoding="utf-8") as f:
                    f.write(driver.page_source)
                print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
            return None, None

        # セグメントコンテナの内容をログに記録
        if not quiet:
            print("セグメントコンテナのHTML:", str(segments_container)[:2000])

        # トランスクリプトのセグメントを取得(完全なセグメントのみ)
        segments = segments_container.find_all('div', class_='segment style-scope ytd-transcript-segment-renderer')
        if not segments:
            if not quiet:
                print("完全なトランスクリプトのセグメント(segment style-scope ytd-transcript-segment-renderer)が見つかりませんでした")
            segments = segments_container.find_all('div', class_=lambda x: x and 'ytd-transcript-segment-renderer' in x)
            if segments:
                if not quiet:
                    print("代替セレクタでセグメントが見つかりました:", len(segments))
            else:
                if not quiet:
                    print("代替セレクタでもセグメントが見つかりませんでした")
                    driver.save_screenshot("transcript_error.png")
                    with open("transcript_error.html", "w", encoding="utf-8") as f:
                        f.write(driver.page_source)
                    print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
                return None, None

        # VTTファイルを作成
        vtt = webvtt.WebVTT()
        if not quiet:
            print(f"トランスクリプトセグメント数: {len(segments)}")

        # トランスクリプトの各セグメントを処理
        i = 0
        while i < len(segments):
            segment = segments[i]
            if not quiet:
                print(f"セグメント {i+1} のHTML:", str(segment)[:500])

            # タイムスタンプを取得
            timestamp_elem = segment.find('div', class_='segment-timestamp style-scope ytd-transcript-segment-renderer')
            timestamp = timestamp_elem.text.strip() if timestamp_elem else None

            # テキストを取得
            text_elem = segment.find('yt-formatted-string', class_='segment-text style-scope ytd-transcript-segment-renderer')
            text = text_elem.text.strip() if text_elem else None

            # テキストがなく、次のセグメントにテキストがある場合、マージを試みる
            if not text and i + 1 < len(segments):
                next_segment = segments[i + 1]
                next_text_elem = next_segment.find('yt-formatted-string', class_='segment-text style-scope ytd-transcript-segment-renderer')
                next_timestamp_elem = next_segment.find('div', class_='segment-timestamp style-scope ytd-transcript-segment-renderer')
                
                if next_text_elem and not next_timestamp_elem:
                    text = next_text_elem.text.strip()
                    if not quiet:
                        print(f"セグメント {i+1} にテキストなし。セグメント {i+2} のテキストをマージ: {text}")
                    i += 1

            if not quiet:
                print(f"セグメント {i+1}: タイムスタンプ={timestamp}, テキスト={text}")

            if not timestamp or not text:
                if not quiet:
                    print(f"セグメント {i+1} のタイムスタンプまたはテキストが欠けています。スキップします")
                i += 1
                continue

            # タイムスタンプを秒に変換
            try:
                time_parts = timestamp.split(':')
                minutes = int(time_parts[0])
                seconds = int(time_parts[1])
                start_time = minutes * 60 + seconds
                end_time = start_time + 2  # 仮に2秒
                start_str = f"{start_time // 60:02d}:{start_time % 60:02d}.000"
                end_str = f"{end_time // 60:02d}:{end_time % 60:02d}.000"
            except (ValueError, IndexError) as e:
                if not quiet:
                    print(f"セグメント {i+1} のタイムスタンプ解析エラー: {e}")
                i += 1
                continue

            # WebVTTキャプションを追加
            caption = webvtt.Caption(
                start=start_str,
                end=end_str,
                text=text
            )
            vtt.captions.append(caption)
            i += 1

        if not vtt.captions:
            if not quiet:
                print("VTTキャプションが生成されませんでした。セグメントに有効なデータがない可能性があります")
                driver.save_screenshot("transcript_error.png")
                with open("transcript_error.html", "w", encoding="utf-8") as f:
                    f.write(driver.page_source)
                print("ページのHTMLを transcript_error.html に、スクリーンショットを transcript_error.png に保存しました")
            return None, None

        if not quiet:
            print("VTTキャプションを生成しました")
        return vtt, video_id

    finally:
        driver.quit()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("使用法: python get_vtt_from_youtube.py <YouTube_URL> [--quiet]")
        sys.exit(1)

    url = sys.argv[1]
    quiet = "--quiet" in sys.argv

    try:
        video_id = extract_video_id(url)
        vtt, extracted_video_id = extract_youtube_transcript_to_vtt(url, quiet)
        if vtt:
            output_file = f"{extracted_video_id}.vtt"
            if os.path.exists(output_file):
                print(f"警告: {output_file} は既に存在します。上書きしますか? [y/N]")
                if input().lower() != 'y':
                    print("処理を中止しました")
                    sys.exit(1)
            print(f"生成されたVTT内容を {output_file} に保存します")
            vtt.save(output_file)  # webvttライブラリで直接保存
            print(f"{output_file} を保存しました")
        else:
            print("トランスクリプトの取得に失敗しました")
    except ValueError as e:
        print(f"エラー: {e}")
        sys.exit(1)