顯示具有 Python 標籤的文章。 顯示所有文章
顯示具有 Python 標籤的文章。 顯示所有文章

2025年4月23日 星期三

OpenSCAD: 遮柵式魔幻卡

2025年4月23日 星期三

底下的照片是 2024年3月時,用 OpenSCAD 製作模型後,再以 3D printer 印出的遮柵式魔幻卡,一個由柵欄構成的模型,柵欄中埋有兩個圖或文,某個視角可以看到第一個圖形,用另一個視角,則可以看到第二個圖形。

底下矩形的遮柵式魔幻卡可以看到英文大寫字母 B (圖1) ,與熊的圖案 (圖2) 變換:

[圖1] 英文大寫字母 B

[圖2] 熊的圖案

底下圓形的遮柵式魔幻卡可以看到中文的春 (圖3) , 與福 (圖4) 兩個字的變換:

[圖3] 春

[圖4] 福

如果仔細看,可以看到印得並不好,導致圖案並不清晰,主要是因為 PLA 的塑料沒做好防潮,水份吸太多,一整個出料不順。我剛開始還以為是模型沒設計好,怎麼印都看不出「魔幻」的效果,一整大失敗,後來才發現,根本只是因為塑料的問題。接著又因為2024年4月的花蓮大地震,把我好不容易才修好的 3D printer 龍門砸壞,不能繼續列印實體,程式就這麼擱了一年多,前幾天將 OpenSCAD 寫的程式整理好,可以給有興趣人玩玩看。

▋ 遮柵式魔幻卡產生器

這個遮柵式魔幻卡產生器是應用在 OpenSCAD 的程序,為了可以直接在網頁瀏覽器中使用,不用安裝任何東西,還能順便將圖片進行一些處理,我將它放在 Google Colab 中,直接在 Google Colab 中製作模型,省去了處理 OpenSCAD 及字型安裝的問題,但是也可以將 OpenSCAD 的產生器下載到電腦,然後離線使用。產生器的網址如下:

▋ 使用方法

魔幻卡的內容可以圖片或是文字。使用圖片就必須先將圖片上載到 Google Colab 的暫存空間,或是直接輸入圖片的網址,讓程式自動擷取。如果是在本機中的 OpenSCAD 中製作模型,圖片必須儲存為 PNG 的格式才能匯入;在 Google Colab 中製作的話,則會自動處理好格式的問題。

✅ 如果想製作文字式的內容:

  • 在「內容1」的「content1」欄位,或「內容2」的「content2」欄位,輸入文字,例如:「春」、「福」。
  • 設定「font_size1」或「font_size2」來調整字型大小。
  • 選取「font_url_1」或「font_url_2」來更換字型。也可以自行上載字型檔,並輸入字型檔的路徑,或是使用網路中公開的字型檔網址。
✅ 如果想製作圖形的魔幻卡:
  • 在「內容1」的「content1」欄位,或「內容2」的「content2」欄位,輸入圖片的路徑。圖片可以自行上載到 Colab 中,或是使用網路公開圖片的網址。
  • 設定圖片的相關參數「auto_resize_1」、「auto_resize_2」、「image_invert1」、「image_invert2」......及「圖片預處理參數」中的選項。

設定好其它參數以後,只要按下設定區塊左側的執行鈕,即可開始進行安裝及製作模型。

▋ 操作示範影片

▋ QA

  • Q: 同樣的照片,為什麼在 Google Colab 中製作的模型效果較好?
    • A: 遮柵式魔幻卡中如果使用圖片,轉為純黑白(非灰階),效果會比較好。在 Google Colab 中的程序中,會預先將圖片轉換,才給 OpenSCAD 使用,所以效果會較好。
  • Q: 在本機的 OpenSCAD 中,為什麼指定了 JPG 的圖片檔了,卻失敗?
    • A: OpenSCAD 的圖片必須使用 PNG 格式,才能匯入。
  • Q: 使用圖片的內容,如果加快製作的時間?
    • A: 可以將圖片的尺寸調小看看。
  • Q: 製作好的模型為什麼字會被切掉?
    • A: 請自行調整字型大小,將數字調小後再試試。


▋ 相關連結




2025年3月19日 星期三

yt-dlp下載錯誤導致 Whisper 無法使用的處理

2025年3月19日 星期三

之前有人反應在使用我的三個 Google Colab 的小工具:

會出現類似這樣的錯誤訊息而卡住:

ERROR: [youtube] BVSF-vSvL6Y: Sign in to confirm you’re not a bot. Use --cookies-from-browser or --cookies for the authentication. See  https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlp  for how to manually pass cookies. Also see  https://github.com/yt-dlp/yt-dlp/wiki/Extractors#exporting-youtube-cookies  for tips on effectively exporting YouTube cookies

[圖1] 有較完整的訊息內容:

[圖1] yt-dlp 下載失敗的截圖

訊息中最重要的關鍵字其實是這兩個:

  • 「yt-dlp」
  • 「Sign in to confirm you’re not a bot」

錯誤是發生在使用「yt-dlp」來下載 YouTube 影片的程序中,應該是 YouTube 的網站在進行「機器人」偵測,Google Colab 的程序無法跟 YouTube 網站「正確互動」,而被擋下來,導致無法下載影片。

除了前面的錯誤訊息,我在測試時,「買一送一」,遇到了第二種錯誤訊息:

ERROR: unable to download video data: HTTP Error 403: Forbidden

[圖2] 是我 yt-dlp 用那麼久以來,第一次遇到的 403 Forbidden 訊息: 

[圖2] yt-dlp 403 Forbidden 的錯誤訊息

YouTube 直接跟我說,無法存取了(很好!我喜歡直接的人!)。

解決的方法

在 Google Colab 中,遇到前面兩種狀況時,目前我的解決方法是執行「中斷連線,並刪除執行階段」,這樣可以達到類似「關機」的效果,將虛擬機關掉,然後我們再將它重啟。

怎麼做呢?很簡單,看 [圖3]、[圖4] 中的紅色箭頭:

[圖3] 點選「中斷連線,並刪除執行階段」

[圖4] 按「是」來確認

當我們利用「中斷連線,並刪除執行階段」,將虛擬機進入「關閉」的狀態以後,只要再重頭將 OpenAI Whisper / Faster Whisper / yt-dlp 的操作程序再執行一次,應該就有機會可以成功了!為什麼說「有機會」呢?哈!我自己在測試時,遇過要兩次才沒被 YouTube 擋下來;幸好不用像「國父」一樣 XDDD

祝您好運,可以畢其功於一役!

相關連結

2024年12月22日 星期日

Python: codecs read UnicodeDecodeError

2024年12月22日 星期日

 HTML5 FUN 的遊戲與工具大多是使用 LimeJS 開發的,LimeJS 其實已經停更快十年,連它依存的 Google Closure Library 也在 2024年8月封存。LimeJS 使用的 Closure Library 、Closure Compiler ...... 其實都是很舊的版本;像 compiler 最後是停在  20130411 的版本,這個舊版本,很多 JavaScript 新的語法它都不認得,當然,應該也存在不少臭蟲。

這幾天在測試,到底 LimeJS 在動得最少的狀況,Closure Library 和 Closure Compiler 可以使用到哪個較新一點的版本?都測試完以後,想讓 LimeJS 至少可以「活過來」,它目前下載原始專案的檔案,連安裝都會失敗。

以 Closure Library 來說,20170816 的版本是可以用的,但是它 build 工具 source.py (closure/bin/build/source.py) 遇到某些檔案會出現錯誤而卡住:

[圖1] Python codecs 讀取檔案失敗

上面最重要的訊息是:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xa5 in position 3457: invalid start byte

查了一下,後來版本 Closure Library 的 source.py 中,用 codecs 來讀取檔案內容,而且指定使用「utf-8-sig」的編碼:

  fileobj = None
  try:
    fileobj = codecs.open(path, encoding='utf-8-sig')
    return fileobj.read()
  except IOError as error:
    err = True
    raise IOError('An error occurred opening or reading the file: %s. %s'
                  % (path, error))
  finally:
    if fileobj is not None:
      fileobj.close()

反覆地測試,查了半天,總算知道卡住的原因了。哈!就那麼巧,我的檔案中居然有好幾個是使用 big5 中文編碼的。Python 的 codecs ,一執行到 read 就出現錯誤,這個情形在舊版使用內建的 open 再 read ,並不會發生的。

解決這個錯誤的方法很簡單,就是先在程式中,先顯示檔名,然後就可以知道卡在哪一個檔案,將有問題的檔案以文字編輯器以 UTF-8 編碼來儲存即可。

有時思考真的不能太僵化,一開始我都懷疑是 Python 環境的問題,但是這一次是各種版本及系統都會發生,完全找錯方向了。

等都弄好以後,再將 LimeJS fork 一份並更新,實在怕哪一天什麼都沒有了,然後 HTML5 FUN 也跟著動不了了。

相關文章

2024年11月10日 星期日

開發 yt-dlp 應用的好幫手 cli_to_api.py

2024年11月10日 星期日

無論是 youtube-dl 或是後繼的分支 yt-dlp 都是用來下載網站影音的好工具,各大知名的影音網站都支援,真的是「超級強」,唯一的缺點它是屬於命令列的工具(對不畏懼指令的人,反而更能把 yt-dlp 的特色完全發揮)。如果不想面對指令,我也弄了一個只要填填資料就能用的,放在這篇文章中,可以試試看:

上面這個小工具是在 Google Colab 的虛薿機以 Python 來處理表單資料,再使用 yt-dlp 的模組來執行影音下載及後續的處理,

關於 yt-dlp 在下指令時,可用的功能選項語法,可以參考官方的說明:

模組中的應用方式可以參考 yt-dlp 的官方說明:

一開始,我以為就是將命令模式用的參數套到模組中就好了,很簡單嘛!哈~真的是太單純了!yt-dlp 的參數包羅萬向,有的參數是用在前端,有的參數是用在後端;同一個功能,名稱及所屬的階層亦不同。感覺直接下指令好像單純一點。

例如,下載影片後,只想儲存 mp3 聲音檔(如果使用預設工具,它是在最後時以 FFmpeg 來進行轉檔),在命令列中使用的是這樣的參數:

--extract-audio --audio-format mp3

但是在 Python 中使用 yt_dlp 模組時,最少必須在設定中使用:

'postprocessors': [{
    'key': 'FFmpegExtractAudio',
    'preferredcodec': 'mp3',
}]

哈!當初為了這個卡關很久,因為一開始,要嘛去搜尋別人的討論或心得;不然就是直接追 yt-dlp 的原始碼。有收穫,但是花了很多時間。

重點來了!昨天在這個網頁中找到了寶:

裡面提到了有一個名為「cli_to_api.py」的工具:

我們只要將在下 yd-dlp 命令時用的參數給 cli_to_api.py ,它就會提供轉換的建議,可以輕鬆地應用在 Python 中。例如,我輸入:

python cli_to_api.py --extract-audio --audio-format mp3

它就給我這樣的內容:

The arguments passed translate to:

{'final_ext': 'mp3',
 'format': 'bestaudio/best',
 'postprocessors': [{'key': 'FFmpegExtractAudio',
                     'nopostoverwrites': False,
                     'preferredcodec': 'mp3',
                     'preferredquality': '5'}]}

Combining these with the CLI defaults gives:

{'extract_flat': 'discard_in_playlist',
 'final_ext': 'mp3',
 'format': 'bestaudio/best',
 'fragment_retries': 10,
 'ignoreerrors': 'only_download',
 'postprocessors': [{'key': 'FFmpegExtractAudio',
                     'nopostoverwrites': False,
                     'preferredcodec': 'mp3',
                     'preferredquality': '5'},
                    {'key': 'FFmpegConcat',
                     'only_multi_video': True,
                     'when': 'playlist'}],
 'retries': 10}

真的是太令人感動了!愛死開源的社群了,讓人功力馬上大增!

另一個例子,如果想讓 yt-dlp 可以將有分章節的 YouTube 影片,下載後一個章節儲存一個檔案,命令列可以使用這個參數:

--split-chapters

使用  cli_to_api.py 來轉換一下:

The arguments passed translate to:

{'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'}]}

Combining these with the CLI defaults gives:

{'extract_flat': 'discard_in_playlist',
 'fragment_retries': 10,
 'ignoreerrors': 'only_download',
 'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'},
                    {'key': 'FFmpegConcat',
                     'only_multi_video': True,
                     'when': 'playlist'}],
 'retries': 10}

關鍵的設定是:

{'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'}]}

真是要命!害我鬼打牆,一直以為用「'split_chapters': True」,然後下指令明明成功了,在 Python 中,就是沒效果。

另外,以 chapters 儲存為什麼檔名的語法,順便筆記一下,命令列的參數:

-o "chapter:%(title)s-%(section_number)02d-%(section_title)s.%(ext)s"

用在 embedding 時:

'outtmpl': {'chapter': '%(title)s-%(section_number)02d-%(section_title)s.%(ext)s'}

怕檔名有用到特列的字,保險一點,還可以再加上 --windows-filenames 參數:

'windowsfilenames': True

有了  cli_to_api.py 這個小工具,真的是幫了大大的忙,讓人可以更體驗到 yt-dlp 這工具的強大。

相關連結


2024年11月1日 星期五

人臉偵測:使用 deface 遮蔽照片或影片中的人臉

2024年11月1日 星期五

有沒有自動將照片或是影片中的人臉打馬賽克的工具?現在人臉偵測的技術已經很成熟,甚至都可以辨識誰是誰了!

以前玩過 Python + OpenCV 進行辨識,這幾天又開始研究人臉偵測。找資料時玩到 ORB-HD 的 deface 。它可以在影片或是照片中,找出所有人臉,後續可以在人臉上進行模糊處理、抹成黑色的、以圖片覆蓋,或是加上馬賽克。原始碼在 GitHub 中:

下面是以 deface 將所有人臉以小熊圖示覆蓋的結果:

[圖1] deface 以圖示遮蔽人臉的結果

個人滿欣賞 deface 的簡潔,要說缺點的話,應該是想使用必須有 Python 的環境,而且是用打指令的方式來操作。

為了方便使用,可以開啟我在 Google Colab 中建立好的程序檔,會自動安裝,也不用打指令。準備好照片並上載,填表單、設定參數即可執行。

工具的網址

工具的網址如下:

如何使用 deface

打開前述的網址以後,透過以下幾個步驟來完成遮蔽人臉:

  1. 上載照片。
  2. 複製照片在上載空間中的路徑。
  3. 填入照片在工具中的檔案路徑。
  4. 設定其它選項。
  5. 啟動並執行程序指令。

詳細的操作說明可以觀看以下影片:

註:影片有字幕

更新記錄

  • 2024-10-31 建立 Google Colab 筆記本



2024年7月22日 星期一

OpenAI Whisper : 英文音檔變中文字幕

2024年7月22日 星期一

前幾天利用 Faster Whisper 轉 VOA Learning Englishhttps://learningenglish.voanews.com/ ) 的 MP3 音檔為 SRT 字幕檔時,因為忘了設定語音的語音代碼,就這麼用了前一次使用的中文的代碼「zh」,哈!也太奇妙了!Whisper 真的給了我中文的字幕吔!為了證明自己不是在作夢,又重新用了另一個英文的音檔,一樣的,語言代碼使用「zh」,重新玩一次,輸出結果還是中文!語言代碼改用「ja」,就變成日文了(圖1),不過日文似乎比較不穩定,常會出現英文的。

[圖1]  英文音檔輸出日文的字幕檔

下面來以 July 21, 2024 這篇「Evidence of ‘Rotten Egg’ Gas Found on Jupiter-like Exoplanet」為例,簡單地記錄一下,怎麼將 VOA Learning English 的音檔轉為中文字幕檔。

先開啟 VOA 的頁面,打開底下這個網址:

[圖2] 找出 VOA 文章音檔下載網址

如 [圖2] 在文章的語音播放器右下角有一個「Direct link」,點一下即可出現 MP3 的下載清單,對準其中一個按滑鼠右鍵,並選取「複製連結網址」。接下來就可以將網址貼到我之前設計的 Faster Whisper 或是 OpenAI Whisper 的 Google Colab 筆記本中了。

以 Faster Whisper 為例,如 [圖3] ,

[圖3] Faster Whisper 的設定

進行幾項設定:

  • url : 「聲音檔的來源」貼上由 VOA Learning English 複製來的 MP3 網址。
  • lang : 語音的語言代碼如果想要英文的字幕檔,就選「en」;想要中文的,就選「zh」。
  • outputFormat : 輸出格式選「srt」。
  • modelType : 「使用哪一種辨識模型」選取「large-v3」。
  • initial_prompt : 「提示語」如果是想輸出繁體中文,就選「以下是繁體中文的句子」。
都設定好,就可以按左側的執行鈕(三角形的播放圖示)。按完就等候結果了。

[圖4] 語言代碼選「zh」就輸出中文字幕檔

[圖5] 語言代碼選「en」就輸出英文字幕檔

看看上面 [圖4] 的語言代碼選「zh」,最後輸出中文的字幕檔;[圖5] 的語言代碼選「en」,最後輸出英文的字幕檔。它們都是用這個 MP3 音檔來進行語音辨識的:

OpenAI Whisper 明明只支援將其它語言語音轉文字以後,翻譯為英文,卻可以這樣玩;查了一下,有人說這可能是 OpenAI Whisper 的 bug,但是這功能也太好用了,希望不會從專案中移除。

接下來,我想試著看看能不能將兩種不同語言的字幕檔合而為一,這樣子搭配 HTML5 FUN Audio Player 來使用:

看看 OpenAI Whisper 和 Bing Translator 誰翻譯得好 ^_^

相關連結




2024年6月24日 星期一

Python: BeautifulSoup 與 querySelectorAll

2024年6月24日 星期一

上週接收了好心同事一整套的英文書 I Wonder Why (Kingfisher 2004版)。查了一下,新版的在書上有附語音檔的 QR code,跟小孩子說,沒關係,只要找到一個連結,應該就都能找出來了。

「將~將~」,真的找到了:

在這個連結的頁面中,除了該冊每兩頁有音檔以外,也有其它冊的連結,這樣子真的是一個連結全部搞定了。

音檔可以下載到載具中,這樣子就可以離線使用;但是要一個個手動按下載嗎?二十本書,應該會按到手廢掉了。

分析了一下網頁的原始碼,果然很結構化,這樣子要找出音檔的連結就方便多了。

剛好前幾天有示範 JavaScript 的 querySelector 跟 querySelectorAll 的應用給小孩子看,順便再複習一下,如何在頁面中找出網址。在瀏覽器開啟前述頁面,然後在開發人員工具中的 Console ,使用這樣的語法:

mp3 = '';
var links = document.querySelectorAll('.synopsis-wrapper li a');
for(var i=0; i<links.length; i++) {
  url = links[i].href;
  res = await fetch(url);
  html = await res.text();
  var parser = new DOMParser();
  doc = parser.parseFromString(html, 'text/html');
  doc.querySelectorAll('source:not([src*="_extras"])').forEach(s=> mp3+=s.src+'\n');
}
console.log(mp3);

最後會將所有書的 mp3 音檔連結,一行行合在一起呈現。

看來網站是有防跨域擷取的,所以使用瀏覽器的 fetch 抓網頁,只能在 I Wonder Why 的頁面中才能成功執行。

由音檔的網址來分析,其實主要分為兩種:

  • insides
  • extras

非「extras」的才是我要下載的。為什麼不說是「insides」的才是我要下載的?

哈!本來我是用:

querySelectorAll('source[src*="insides.mp3"]')

中括號的 Attribute selectors 限定 src 的內容帶有 insides 的才留著,結果有兩本書的內容就解析不到音檔的網址。人工查了一下,才發現一個是會在 .mp3 前多了 new,另一個則是連 insides 都沒有。所以最後使用了 not([src*="_extras"]) ,這樣一來,非「extras」的條件,簡化了語法,不然又要打很多字來設條件了。

擷取出來的音檔網址要怎麼下載檔案?

最方便的就是使用 wget,它有提供「-i」的參數,可以讀入存有網址清單的純文字檔,然後一個個的下載回來。

如果把這麼多檔案放在一個資料夾裡面,要使用實在不方便,所以決定用 Python 來試試。如果在 Google Colab 中執行,分析完音檔的網址,直接就儲存到 Google Drive 中,這樣子在行動載具,只要由 Google Drive 中開啟來用;或是乾脆整個下載到載具儲存更好。

在 Python 中想要使用類似 JavaScript DOMParser + querySelectorAll 的功能,第一個想到的就是 BeautifulSoup。BeautifulSoup 的 select 語法和 querySelectorAll 一樣,實在是太棒了。

底下將整個語法貼在下面:

import re
import os
import requests
import urllib.request
from bs4 import BeautifulSoup

rootFolder = 'drive/MyDrive/00-i-wonder-why'

menuPageUrl = 'https://audio.panmacmillan.com/i-wonder-why-snakes'
html = requests.get(menuPageUrl).text
soup = BeautifulSoup(html, 'html.parser')
links = soup.select('.synopsis-wrapper li a')

for a in links:
  url = a.get('href')
  html = requests.get(url).text
  soup = BeautifulSoup(html, 'html.parser')
  title = re.findall(r'i-wonder-why-(.*)$', url)[0]
  print(title)
  source = soup.select('source:not([src*="_extras.mp3"])')
  print(len(source))
  folder = f"{rootFolder}/{title}"
  if not os.path.exists(folder):
    os.makedirs(folder)
  list_filename = f'{folder}/00-list.txt'
  list_txt = ''
  for s in source:
    mp3URL = s.get('src')
    pp = re.findall(r"pp(\d+)-(\d+)[^\.]*\.mp3", mp3URL)
    filename = title
    for n in pp[0]:
      filename +=  '-' + n.rjust(2, '0')
    filename += '.mp3'
    list_txt += f'{filename}\r\n'
    #print(mp3URL)
    filename = f"{folder}/{filename}"
    urllib.request.urlretrieve(mp3URL, filename)
  if list_txt != '':
    f = open(list_filename, 'w')
    f.write(list_txt)
    f.close()

音檔下載後,將檔案名稱改得簡單一點,並儲存到各冊自己的資料夾中;也順便將音檔的清單存入各資料夾中的「00-list.txt」文字檔中。

「00-list.txt」是我為下一階段所做的準備。為了方便聽音檔時可以快速檢索,我使用 OpenAI Whisper ( 後來改用 Faster Whipser ) ,將音檔進行語音辨識,並輸出為字幕檔,因為一句句都帶有時間截記,要快速重聽某一句就方便多了。哈!我之前分享過的 OpenAI Whiper ,跟 Faster Whisper ,經過我的打造,都支援由文字檔中讀取音檔清單,然後也可以自行設定輸出的資料夾,輸入、輸出都設定到 Google Drive 我放 I Wonder Why 的音檔資料,這樣子就可以「一條龍」了!兩個工具可以參考之前的文章:

為什麼後來改用 Faster Whisper  ? 主要是 OpenAI Whisper 比較耗資源,解譯完一冊書的音檔,第二冊進行到一半,就被重置,這實在太令人氣結了。

不過,用著用著,才發現自己寫的程序有一些小臭蟲,前面的 「00-list.txt」中放的是只有音檔的檔案,因為不是絕對路徑,一直出現了找不到音檔的訊息,並沒有進行語音辨識;另外,輸出的資料夾如果沒有先建立好,也不會照設定儲存到雲端硬碟中,針對這些問題,會再更新到公開的版本中。

有了音檔,有了字幕檔,目前我們使用 oTranscribe 在 iPad 中聽語音 :

如果遇到需要查中文的,就直接將字詞選取以後,使用 iOS 內建的字典來看,整體看起來,還算可以。

字幕檔變雙語?試了一下,也滿好玩的,一行英文,一行中文,利用 Microsoft+Copilot ChatGPT 就能製作了,目前使用這樣的 prompt

translate the following subtitles text to traditional Chinese , treat as one continuous text, keep the source format and append Chinese to the next line of English :

ChatGPT 3.5

Translate the English subtitles text into traditional Chinese, add Chinese after the line of English. the subtitles is:

產生的雙語字幕檔,還需要利用 Regular Expression 處理一下,不過,一道指令就可以完成了。

還在構思是否要來寫個 HTML5 的閱讀小工具,可以比 oTranscribe 更方便的聽讀、查閱。

相關連結




2024年4月2日 星期二

Python : 轉換 DataFrame 帶有逗號的數字字串為純數字

2024年4月2日 星期二

在設計「雄:Python : 匯出 PDF 表格為試算表資料」中的轉換工具,由 PDF 擷取而來的資料被轉為pandas 的 DataFrame,最後使用 DataFrame 的 to_excel 輸出為 Excel 格式的檔案。不過如果照預設值,輸出的資料在Excel中,都是「文字」的格式;此外同事提供的原始資料,除了流水號的欄位,其它欄位的數字都有加上逗號(例: 12,345、7,890),所以在將「文字格式」的數字轉為數字型態時,得多考慮這一點。

在 Python 中,將文字型態的數字,轉為數字型態的方法有很多,不過,試了一下,如果想將「12,345」轉為「12345」,使用 locale 的 atof 或是 atoi 應該是較簡潔,例如:

import locale
from locale import atof

locale.setlocale(locale.LC_NUMERIC, '')
atof('12,345')

但是如果遇到不是數字的內容,或是空字串,例如:

atof('這不是數字')
atof('')

就會出現類似這樣的錯誤訊息:

ValueError: could not convert string to float: ''

所以在轉換的時候,還需要檢查一下是否為數字的。

判斷是否為數字,可以使用 Python 的 isnumeric() ,不過,像以下的格式:

  • 12,345
  • -12345
  • 12.345

因為帶有逗號、減號或小數點,isnumeric() 都會傳回 False,所以我先利用 re.sub ,將非數字的符號先拿掉後,再用 isnumeric() 來判斷。

綜合前面的條件,利用底下的 convert_number_strings_to_numbers ,就可以用來將 df (pandas 的 DataFrame) ,指定的欄位 columns (欄位順號 list),轉為 float 數字:

def convert_number_strings_to_numbers(df, columns):
  locale.setlocale(locale.LC_NUMERIC, '')
  for i in columns:
    df[i] = df[i].apply(lambda x: x if x=='' or not re.sub(r'[,.-]', '', x).isnumeric() else atof(x))
  return df

相關文章


2024年4月1日 星期一

Python : 匯出 PDF 表格為試算表資料

2024年4月1日 星期一

很多行政工作如果規畫、整合得當是可以不用花那麼多時間的;反之,沒有整合,就是整死人。記得以前看學校幹事們忙著在電腦上剪剪貼貼資料,忙得人仰馬翻的,總覺得,為什麼運用電腦了,還需要這樣子「愚公移山」;關係夠好,看不下去了,就會幫忙弄些小工具,來處理資料。前幾天同事問我有沒有辦法將別人 PDF 檔中的表格資料匯出到試算表,並且將列變成行、直變橫?PDF 中的表格長這樣子:

第一個想法,Python 應該可以!幾個程序能做到,轉檔應該就有望了:

  • 以 Python 讀取 PDF 的資料,並解析出表格文字內容。
  • 去掉不要的資料。
  • 將表格內容進行旋轉(transpose)。

由 PDF 讀入表格資料

讓 Python 讀入 PDF 資料,並解析出表格文字內容,我試了:

  • tabula-py
  • Camelot (camelot-py)

測試過,感覺 Camelot 比較可以跟後續的資料旋轉接軌,就專心研究 camelot-py 了。

關於 camelot-py 的安裝

在 Windows 上使用 camelot-py 大概會遇到這個錯誤訊息:

OSError: Ghostscript is not installed. You can install it using the instructions here: https://camelot-py.readthedocs.io/en/master/user/install-deps.html

主要是因為讀入 PDF 檔案時,如果沒有指定「backend」參數,它預設會使用預設值「backend="ghostscript"」,而大部份的電腦中可能沒安裝ghostscript,有興趣可以參考錯誤訊息中的說明文件:

因為 ghostscript 的安裝顯得較複雜,所以我選擇在 Windows 中用「backend="poppler"」,只要先執行以下兩行指令安裝 pdftopng 跟 opencv 即可:

pip install pdftopng
pip install opencv-python

倒過來,如果在 Google Colab 的環境中,安裝 pdftopng 反而會累死人(我是沒成功),安裝 ghostscript 容易多了:

!apt install python3-tk ghostscript
!pip install  ghostscript

關於 camelot-py 的使用

假設 pdf_file_name 是 PDF 的路徑,pages 中放了要讀入資料的頁碼 list,只要這樣就可以讀取資料:

import camelot
pdfTable = camelot.read_pdf(pdf_file_name, pages=pages)

如果不是用 ghostscript,就用:

import camelot
pdfTable = camelot.read_pdf(pdf_file_name, pages=pages, backend="poppler")

接下來我們就可以針對 pdfTable 來存取(轉換)資料,詳情可以參考 camelot-py 中,有關 Table 的說明:

我使用 pdfTable[0].df ,將抓到資料轉為 pandas.DataFrame 的格式,方便後續的資料處理。

資料處理

前面提到利用 pdfTable[0].df ,可以將指定頁資料轉為 pandas.DataFrame 物件,假設將內容指定給變數 df,我想針對 df 再進行一些處理:

  • 只取出指定的列(之後會旋轉為欄)。
  • 去掉原始資料最右側的「小計」那欄。
  • 暫存原始資料最左側欄的資料(最後為試算表中的欄位名稱)。
  • 去掉流水號不是數字(空格或是「以下空白」)的資料。
  • 將一頁頁資料合併在一起

pandas 的 DataFrame,在存取資料時,幾個關鍵詞跟對象有關:

  • index
  • colunms
  • axis

幾個關鍵詞跟過濾、移動指標有關:

  • isin
  • iloc
  • loc

資料的刪除、旋轉、合併的關鍵詞:

  • drop
  • transpose
  • concat

詳細的說明都可以在pandas的網站查到:

為了寫這個資料轉換的工具,第一次玩  Camelot 和 pandas,雖然還沒有很深入研究,但工具有了初步的成果了,將它移植到 Google Colab 中,想玩玩看(哈!不能提供有個資的 PDF 啦!) ,或是對原始碼有興趣(別嫌我,醜是一定的,就好玩,亂寫的),網址如下:

pdf-to-excel.ipynb 的截圖

改天再補記一下曾經卡關很久的地方。

相關文章


2024年3月18日 星期一

Python: googletrans 與 bilingual_book_maker

2024年3月18日 星期一

2023年3月應朋友的要求,將開源的專案「bilingual_book_maker」可以在 Colab 中使用(參見:雄:OpenAI : ChatGPT 應用 : 製作雙語電子書),利用它可以把 EPUB 格式的電子書變成「雙語」的內容。前一陣子陸續有人反應有問題,不過,因為我根本沒在使用,加上有時問題會在一陣子後又消息了,所以沒有積極地去查原因。前天換有在使用的朋友跟我說了,哈!開始認真地找解方。

底下記錄一下排除問題的關鍵。

httpx 版本的問題

googletrans 已經滿久沒更新了,而 openai 持續地在更新,但是兩者都有用到 httpx,一個要舊版的,一個要新版的,因此安裝完 googletrans 以後,出現了「dependency conflicts」的錯誤訊息:

  Building wheel for googletrans (setup.py) ... done
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
openai 1.14.1 requires httpx<1,>=0.23.0, but you have httpx 0.13.3 which is incompatible.

httpx 版本的衝突,由訊息看來,因為 googletrans 是後安裝的,所以最後 httpx 用的版本是 0.13.3 ,而不是 openai 要的版本( >=0.23.0 )。這也導致開始翻譯時,出現了這些訊息:

Traceback (most recent call last):
  File "/usr/local/bin/bbook_maker", line 5, in <module>
    from book_maker.cli import main
  File "/usr/local/lib/python3.10/dist-packages/book_maker/cli.py", line 7, in <module>
    from book_maker.translator import MODEL_DICT
  File "/usr/local/lib/python3.10/dist-packages/book_maker/translator/__init__.py", line 2, in <module>
    from book_maker.translator.chatgptapi_translator import ChatGPTAPI
  File "/usr/local/lib/python3.10/dist-packages/book_maker/translator/chatgptapi_translator.py", line 7, in <module>
    from openai import AzureOpenAI, OpenAI, RateLimitError
  File "/usr/local/lib/python3.10/dist-packages/openai/__init__.py", line 8, in <module>
    from . import types
  File "/usr/local/lib/python3.10/dist-packages/openai/types/__init__.py", line 5, in <module>
    from .image import Image as Image
  File "/usr/local/lib/python3.10/dist-packages/openai/types/image.py", line 5, in <module>
    from .._models import BaseModel
  File "/usr/local/lib/python3.10/dist-packages/openai/_models.py", line 23, in <module>
    from ._types import (
  File "/usr/local/lib/python3.10/dist-packages/openai/_types.py", line 23, in <module>
    from httpx import URL, Proxy, Timeout, Response, BaseTransport, AsyncBaseTransport
ImportError: cannot import name 'BaseTransport' from 'httpx' (/usr/local/lib/python3.10/dist-packages/httpx/__init__.py)

openai 比較重要,試著以它為主,讓 googletrans 使用較新版本的 httpx 看看,也就是安裝 googletrans 時,不要檢查 dependency,將原本的安裝指令:

!pip -q install  googletrans==4.0.0-rc1

多加「--no-dependencies」改為:

!pip -q install --no-dependencies googletrans==4.0.0-rc1

httpcore 的問題

前面雖然解決了 googletrans 安裝時的問題,執行時,換 httpcore 有問題,出現了這樣的錯誤訊息:

AttributeError: module 'httpcore' has no attribute 'SyncHTTPTransport'

查了一下,可以在使用 googletrans 前,先執行:

import httpcore
setattr(httpcore, 'SyncHTTPTransport', 'AsyncHTTPProxy')

利用這兩行來 patch,只要比 googletrans 先執行,就不會出現 AtributeError。

httpx[http2]

本以為可以順利執行 google 翻譯了吧!結果又出現這樣的訊息:

Using http2=True, but the 'h2' package is not installed. Make sure to install httpx using `pip
install httpx[http2]`.

不過,這看起來比較好解決,就照提示,安裝 httpx[https] 就好,所以在安裝 googletrans 之前,先執行:

!pip -q install httpx[http2]

經過以上的修正,終於可以讓 googletrans 順利地和 bilingual_book_maker 搭配,以 google 翻譯來進行翻譯。

不過,為了讓使用更有彈性來選擇是否以 googletrans 幫 bilingual_book_maker 執行 google 翻譯的功能,我加上了「install_googletrans」的設定參數,如果勾選了,就使用 googletrans ,否則使用 bilingual_book_maker 專案內建的功能。這樣子,必要的時候,可以選擇關閉我亂改的部份,直接執行 bilingual_book_maker,也方便除錯。

這個雖然是自己沒在使用的工具,累積了除錯及解決問題的能力,時間沒有白花,收穫還挺多的,相信它是一個善的循環。

相關文章


2024年2月21日 星期三

Colab : 讓 OpenSCAD 可以輸出圖片

2024年2月21日 星期三

 在一般的電腦中,OpenSCAD 可以利用 -o xxx.png ,來輸出模型的預覽圖片,但是相同的指令在 Google Colab 中卻會出現類似這樣的錯誤訊息:

Compiling design (CSG Products normalization)...
Normalized CSG tree has 102 elements
Unable to open a connection to the X server.
DISPLAY=
Can't create OpenGL OffscreenView. Code: -1.

然後圖片並沒有輸出任何內容。

主要的原因是 OpenSCAD 輸出圖片時,需要有一個「顯示器」,但它在 Colab 這種遠端的虛擬機環境中並找不到,就出現錯誤訊息了。

沒關係,既然是虛擬機,那就安裝 Xvfb 和 pyvirtualdisplay,來一個虛擬的顯示器吧!

在安裝完 OpenSCAD 後,順便加上這樣的指令,來安裝 Xvfb 和 pyvirtualdisplay:

if not os.path.exists('/usr/bin/Xvfb') :
  print('安裝 xvfb ...')
  !apt-get -qq install xvfb 2>/dev/null >/dev/null
try: from pyvirtualdisplay import Display
except:
  print('安裝 pyvirtualdisplay ...')
  !pip -q install pyvirtualdisplay

要啟用虛擬顯示器就加上這兩行:

from pyvirtualdisplay import Display
Display().start()

有了 Xvfb + pyvirtualdisplay 助攻,就可以在 Colab 中,順利地讓 OpenSCAD 輸出圖片了。

相關文章


2024年1月3日 星期三

Colab : The secret HF_TOKEN does not exist in your Colab secrets

2024年1月3日 星期三

 有人留言反應「雄 : 以 Faster Whisper 將影音辨識為文字檔案(字幕或逐字稿)」的 Colab 筆記本執行完有錯誤訊息,前幾週還有用過,試了一下,會出現類似這樣的訊息:

/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:72: UserWarning:
The secret `HF_TOKEN` does not exist in your Colab secrets.
To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.
You will be able to reuse this secret in all of your notebooks.
Please note that authentication is recommended but still optional to access public models or datasets.
warnings.warn(

追了一下 Faster Whisper 的原始碼,應該卡在「faster_whisper /utils.py」中的「download_model」,用來下載語音辨識模型資料的程序。它使用了「huggingface_hub」來下載相關檔案,而 huggingface_hub 兩週前的 v0.20.0 起,支援讀取 Colab 的 Secret 中設定的 HF_TOKEN 參數內容:

Authentication has been greatly improved in Google Colab. The best way to authenticate in a Colab notebook is to define a HF_TOKEN secret in your personal secrets. When a notebook tries to reach the Hub, a pop-up will ask you if you want to share the HF_TOKEN secret with this notebook -as an opt-in mechanism. 

也不知道哪裡出了問題,它說不認證也可以讀到 HugginFace Hub 專案中的檔案,卻卡住了。

試了半天,沒辦法解決 Colab 中已內建的較新版 huggingface_hub, 好吧!反正 Faster Whisper 目前只要 0.13 版以上就能運作,就先安裝舊版的 huggingface_hub,在筆記本安裝 Faster Whipser 的程序前,加上了:

!pip -q install huggingface_hub==0.19.4

哈!先求能動,等不行時再來想別的辦法。

後記:(2024.01.08)

huggingface_hub 已經有最新版 (0.20.2)可以解決 Colab 卡住的問題,所以安裝最新版的 huggingface_hub  也能解決問題,用這道指令來安裝最新版的 huggingface_hub:

!pip install -q -U huggingface_hub


相關文章

2023年11月9日 星期四

以 Faster Whisper 將影音辨識為文字檔案(字幕或逐字稿)

2023年11月9日 星期四

前言

為了方便製作影片或是音檔的字幕檔、逐字稿文字檔, 2023年2月底,我在 Google Colab 筆記本中,結合了 OpneAI Whisper 及 yt-dlp,搭配 Colab 簡單的網頁界面,可輸入像是影音網址(或是檔案路徑)、Whisper 的語音辨識模型大小、輸出格式......等自訂的參數;設定完參數,按個「執行」鈕,就可以不用管程式的安裝及享用 Colab 提供的 GPU 運算力,輕鬆坐等接收語音辨識的結果 (詳見「雄:使用 OpenAI Whisper 製作影音的字幕或逐字稿」)。

好一陣沒錄教學影片,前幾天為了幫新錄的影片加上字幕,才發現在 Colab 中安裝 OpenAI Whisper 似乎要多花很多倍的時間,以我片長不到五分鐘的影片來說,語音辨識只要幾秒鐘,等待安裝卻要幾分鐘,實在不成比例(註:2023.11.22 再次使用 OpenAI Whisper,安裝時間要很久的問題已不存在,看起來應該是相關套件的版本已跟上,不用樣樣都需要重新編譯,回復到可以順順地使用 OpenAI Whisper的狀態。)。於是開始找是否有更好的方案,找到了 guillaumekln (Guillaume Klein) 的 Faster Whisper 專案:

Faster Whisper 是使用 CTranslate2 的界面加上 OpenAI Whisper 開放出來的模型,可以大幅減少記憶體及其它資源的耗用,又能有與原 OpenAI Whisper 差不多的輸出結果,這樣是不是很讚!

經過這幾天的實測,至少安裝程序等候的時間是少很多、耗的資源小很多~~,輸出的內容和 OpenAI Whisper 的結果差不多,真的是小而美。要說缺點的話,大概是因為它目前沒有提供直接輸出成字幕格式的檔案,不過,這算是小事,只要用其它的套件,多寫幾行程式碼來補足功能,轉換一下輸出格式就好了,哈!相關程序我都在底下放在 Colab 中的工具處理好了。

工具網址

整合在 Colab 中的「Faster-Whisper-語音辨識-輸出文字檔」工具,放在這個短網址中,開啟後就能使用:

使用方法

先開啟工具的網址,進入頁面,往下捲,在說的的下方,應該會有如 [圖一] 的輸入區:

[圖1] Faster Whisper 的操作程序

1.上載檔案:如果想上載電腦中的影片或是音檔,就按 [圖1] 箭頭1所指的 [檔案] 圖示,就可以將要進行語音辨識的影音檔案上載。上載完的檔案或是使用 Google 雲端硬碟的檔案,如何複製檔案的路徑,請自行參考「操作示範影片」中的示範。

2.在「url」中填入影音的來源:

  • 存放在網路的「公開」影音,就貼入網址,YouTube(影片或是播放清單)、FB、雲端硬碟、Vocaroo......等的「公開分享」網址。
  • 在放在電腦中的檔案則需要先上載到 Colab 中,然後再「複製路徑」,將檔案的路徑貼到「url」的欄位中。
  • 如果想批次進行語音辨識,則是將前述的網址,通通先貼到一個文字檔(檔名 xxx.txt),一行一個網址或是路徑,儲存後,再將文字檔上載到 Colab 中,最後再「複製路徑」,將檔案的路徑貼到「url」的欄位中;這樣子,程式會依照文字檔的內容,一行行的進行語音辨識。
3.執行程式:填完「url」的欄位後,可以再看看底下的一些選項有沒有要更改的,確定沒問題,要開始執行語音辨了,就按 [圖1] 綠色箭頭所指的執行圖示。接著就等程式自動安裝及執行語音辨識的程序完成。

詳細的過程請參考底下的操作示範影片。

操作示範影片

底下的影片中介紹如何將影音檔案上載到 Colab 或是利用雲端硬碟中的影片來辨識為文字檔:

Q & A

  • Q : 未付費版的 Colab,Fast Whisper / OpenAI Whisper 能執行多久?
    • A : 因為 Whisper 使用到 GPU ,所以目前一個帳號每天只能使用大概 4小時 (以前是12小時)。
  • Q : 給它播放清單或是清單檔案,為什麼執行到一半,中斷了?
    • A : 如果輸出區有出現錯誤訊息,找一下最後幾行,有沒有類似「private video ...」的關鍵字,如果有,表示某一個影音並不是公開分享的,因為抓不到檔案而中斷程式了;將它從清單中移除再試試看。
  • Q: 出現「403: Forbidden」或是「Sign in to confirm you’re not a bot」的錯誤訊息,如何處理?

相關連結


    2023年3月6日 星期一

    OpenAI : ChatGPT 應用 : 製作雙語電子書

    2023年3月6日 星期一

     最近有個開源的專案「bilingual_book_maker」,將 EPUB 格式的電子書的內容,一段段抓出來後,利用 OpenAI ChatGPT 翻譯以後,再重組輸出成雙語的電子書,專案的網址如下:

    我將程式碼移植到 Google Colab 上玩,只要準備好 EPUB 電子檔及 OpenAI 的 API Key,就能在 Colab 中體驗「bilingual_book_maker」的功能。

    製作工具網址及使用方法

    Colab 筆記本的網址如下:

    請建立自己的副本後再使用,如何利用前述工具來製作雙語的電子書,以下影片中有簡單的介紹:

    如何取得 OpenAI 的 API Key

    OpenAI 的 API Key 可以由底下的網址直接進入管理介面後取得:

    簡單的操作介紹影片:

    如何製作 EPUB 檔案

    製作 EPUB 格式電子書的工具不少,最簡單的方式,可以利用 Google 文件、LibreOffice、Sigil ...... 等工具輸出 .epub。

    要注意的是,目前「bilingual_book_maker」是一段段的方式(以 HTML 的 <p> 分段),所以分段的好壞,應該會影響到效率與效果。

    更新記錄

    • 2024.03.18 openai 使用較新版本的 httpx ,導致 googletrans 4.0.0-rc1 無法正常運作,除了修改安裝程序,讓  googletrans 4.0.0-rc1 可以工作,也新增「install_googletrans」的參數,有勾選才會使用  googletrans 4.0.0-rc 來進行 google 翻譯,不然就是使用 bilingual_book_maker 內建的功能。
    • 2023.04.11 安裝改由 Github 更新;加入 single_translate 的參數,只輸出譯文,不輸出原文。
    • 2023.03.21  bbook_maker 中的 Google 翻譯會有因為電子書內容太多,而未完全翻譯的情形,另外也限定翻為簡體中文,所以改用 googletrans 4.0.0-rc1 來進行翻譯,順便解決設定輸出語言的問題。
    • 2023.03.17 改用安裝 bbook_maker 的方式,安裝最新版本;參數加入 resume_enable 及 translate_tags。
    • 2023.03.07 有時會出現簡體字的問題解決。參見 :
      https://github.com/yihong0618/bilingual_book_maker/commit/2d5972e76d022cda94a9cc9b9d2d011aa9a614f4
    • 2023.03.05 初稿


    2023年2月22日 星期三

    使用 OpenAI Whisper 製作影音的字幕或逐字稿

    2023年2月22日 星期三

    前言(廢話一堆,可忽略不看)

     試了不少影音編輯工具(平台)的自動語音辨識產生字幕的功能以後,發現很多看起來都差不多;後來看到了這個 auto-subtitle 的專案:

    它是使用 OpenAI 的 Whisper 來進行語音辨識,哈!只能說自己實在太孤陋寡聞了,現在才注意到有 OpenAI Whisper。Whisper 有開源,它的專案連結在底下:

    如果已經準備好 Python 的環境,可以將它安裝在本機上,在專案中有簡單的說明。如果想快速測試,那當然是直接使用 Google 的 Colab 來建置最方便。Colab 已經有基本的 Python 環境,Whisper 需要的 ffmpeg 及一些可能需要用到的套件都內建好了。

    好康A~跟您分享

    好東西,只給自己用太可惜了,所以我將自己在本機上實驗的程序,移植到 Google Colab 中,還加上了一些功能,大家可以直接使用,不用管安裝的過程。

    這個 OpenAI Whisper@Colab 有以下的功能:

    • 可輸入 YouTube 影片的網址,產出影片的字幕檔後下載。
    • 可輸入 YouTube 播放清單的網址,產出清單中所有影片的字幕檔,並置入壓縮檔中後下載。
    • 可輸入 Vocaroo 線上錄音的網址,解析出音檔的文字內容。
    • 可讀取上載到 Colab 暫存空間的影音檔案,產出字幕內容後下載。
    v.2 版增強的功能:
    • 可輸入已設定為「公開分享的」Google Drive 影音網址(v.2 版才支援)
    • 可輸入檔名為「.txt」的轉換清單檔案,裡面一行一個要辨識的網址或是檔名,執行時就可以批次進行辨識(v.2 版才支援)
    • 可自訂輸出的資料夾名稱(v.2 版才支援)
    • 可自訂是否要覆蓋已經辨識過的文字檔。(v.2 版才支援)

    工具網址 (2024.10.07 更新過程式)

    這個「OpenAI-Whisper-語音辨識-製作字幕檔」的工具存放在 Google Colab 的筆記本,網址如下:

    註:另一個選擇是使用 Faster Whisper,詳見這一篇:

    影片說明

    底下的影片,簡單地介紹一下如何使用這個工具製作字幕檔:

    重點整理

    關鍵程序截圖並說明如下:

    [圖1] Google Colab 中操作

    ✅ 進行設定:

    如 [圖1] 的箭頭 2 ,輸入影音的路徑、選擇語言代碼、輸出的格式、使用的辨識模型...等設定。

    ✅ 執行程式:

    如 [圖1] 的箭頭 3,按一下「播放」鈕,即可以開始執行 Whisper 的安裝與語音辨識程序。

    ✅ 等候辨識結果:

    使用 OpenAI Whisper 等候的時間,需視影片或聲音檔的聲音長度,及是否使用 GPU 運算(本文中的工具預設使用 GPU);選用 Whisper 的哪一種辨識 Model 也有差異,small 的 model 一定花的時間比 medium 的 model 要少很多,當然,辨識的正確率也會有差別。以前面的介紹影片為例,影片的片長是 5分22秒,未使用 GPU 的情形下,以 OpenAI Whisper  medium 的 model 來辨識,花了快二十分鐘;開啟了 GPU,並使用 large 的 model,才花了一分多鐘。所以建議開啟 GPU 使用(本文中的工具預設使用 GPU,Goolge 讓免費版的  Colab 一天可使用 4 小時左右的 GPU)。

    [圖2] 等候時間隨選用的 model 而有差異

    如何上載電腦的檔案到 Colab 並進行語音辨識

    如果想辨識的影音不在網路上,可以立即上載到 Colab 的「暫存」空間,注意!它是「暫存的」,當我們下回重新開啟 Colab 的筆記本時,上載的檔案會不見哦!下面看一下如何使用這個暫存空間(它的額度和 Google 雲端硬碟是分開算的)。

    ✅ 展開「暫存空間」:

    按一下左側欄中的「資料夾」圖示,即可展開暫存空間來上載或管理檔案。

    [圖3] 展開暫存空間

    ✅ 上載檔案:

    當「暫存空間」展開後,只要將想上載的檔案,以拖曳的方式,拉進「暫存空間」即可。

    [圖4] 以拖曳的方式上載檔案

    溫馨提醒,暫存區是會被清空的

    [圖5] 暫存區是會被清空的警告訊息

    ✅ 設定檔案名稱:

    等影音檔案上載完畢,就可以設定要辨識的檔案名稱,如 [圖7] 箭頭1 ,在「url」的欄位中,輸入檔案的「完整名稱」。

    [圖6] 設定檔案名稱並執行程式

    ✅ 執行程式:

    都設定參數了,就可以按 [圖6] 箭頭 2 所指的「播放」鈕來執行語音辨識的程序。

    Q & A

    • Q : 可不可以辨識自己雲端硬碟中的影音檔案?
      A : 當然可以。看一下 Colab 「暫存區」上方的圖示,其中有一個是「連接雲端硬碟」的圖示,按下去以後,照指示,就可以將雲端硬碟變成暂存區中的一個資料夾來存取檔案了。找到要使用的檔案後,按一下檔案,檔案的右邊會有「三個點點」,按一下「三個點點」即可出現檔案管理的選單,按選單中的「複製路徑」,就可以取得「url」要填入的檔名。
    • Q : 如何加快辨識的速度?
      A : AI 需要大量的運算,如果能打開「GPU」的選項,速度會快很多倍,所以一定要在自己的 Colab 中,選用 GPU 的選項,設定的方法:
      1.在 Colab 上方主選單中,按一下「編輯」。
      2.按一下「筆記本設定」。
      3.在「筆記本設定」的「硬體加速器」中,選「GPU」。
    • Q : 可以使用多久?
      A : 免費版的 Colab ,GPU 一天只能使用4小時,而我放 Colab 的 OpenAI Whisper 或是 Fast Whisper 預設都有使用 GPU 的選項,所以一天只能使用 4 小時;強烈建議不使用時,務必「中斷連線並刪除執行階務」,或是關閉瀏覽器,讓它關掉虛擬機,停止計時。
    • Q: 出現「403: Forbidden」或是「Sign in to confirm you’re not a bot」的錯誤訊息,如何處理?
      A: 請參考這一則「雄:yt-dlp下載錯誤導致 Whisper 無法使用的處理

    相關連結


    自己的雜記(還是廢話,請忽視)

    順便筆記一下,免得忘記又重新掉坑的。

    Windows 7 安裝最近版的 Anaconda ,出現「Failed to create menus」的錯誤訊息而無法安裝。因為系統太舊,無法安裝 Python 3.9,所以卡住。只好改用舊版的 Anaconda,像 2021.05 是使用 Python 3.8 的。舊版的可以在這裡找到:

    最後改安裝「Anaconda3-2021.05-Windows-x86_64.exe」。

    照說安裝完 openai-whisper 後,除了 python 的套件,應該也會有 .exe 的執行檔,但是我在一台沒有安裝過 Python ,全新安裝 Anaconda 的 Windows 10 上,直接執行 whisper 的命令卻出現找不到指令的錯誤訊息。查了一下,原來 whisper.exe 被安裝到使用者目錄(ex. userA) ,類似底下的路徑中:

    Users\userA\AppData\Roaming\Python\Python39\Script 

    為了方便使用,可以將該路徑加入環境變數中。

    Windows 7 的舊版 Anaconda 則是將 whisper.exe 放到 ananconda 目錄中的 scripts 中,該路徑已經在環境變數的 PATH 裡了。版本不同,安裝方法不同,路徑就得特別注意一下。


    2022年11月14日 星期一

    Python : bytes 轉 string

    2022年11月14日 星期一

     在 2019 年底時,曾經針對 Plickers 網站,寫了一個可以利用 .csv 檔,批次匯入題庫的小工具「雄 : Chrome : 擴充功能 : Plickers CSV Import」。很久之前,朋友曾經提到它無法正常運作了,當時初步了解,是因為 Plickers 網站有一些改變,API 呼叫的方式及資料結構略有不同,導致舊的程式無法運作。這兩天有訪客留言,又問到同一個問題,剛好這幾天的研究告一個段落了,於是花了一整個下午,找出了新程序異動的地方,將 Chrome 的擴充功能改好,並上載,等候審核後,即可將 Google 商店中的,更新為 0.6 版。

    有趣的是,2019年時,是 Python 版出發,才有 JavaScript 版的;這一回則是顛倒過來,先改好 JavaScript 版,才準備更新 Python 版。

    本以為應該不難吧!哈!又耗掉了一個晚上,主要是太久沒有研究 Python,對 Python 3 更是陌生,然後就卡在一個小地方,真的是小小的地方:

    • bytes

    • string

    哈!還是 JavaScript 的世界單純!當初在 Python 2.7 時,因為使用了:

    s.encode('utf-8')

    將字串 s 先轉為 utf-8 ,再來進行字串的比對。

    原來在 Python 2.7 中正常的語法,到了 Python 3 卻失效了!後來用 print 將內容顯示,才注意關鍵字「bytes」;原來使用「encode('utf-8')」以後,字串就變成「bytes」型態,而不再是 string 了,難怪比對字串都失敗。

    好的!那何解?

    就再利用 decode 把它變回字串吧!變成:

    s.encode('utf-8').decode()

    真是的,就這麼簡單,花了一個多小時在找問題。

    總算解決問題,順利地將 GitHub 中的程式也更新了。下回再來研究一下,如何在 Plickers 網站中增加有多媒體素材的題庫。

    相關文章



    2022年5月20日 星期五

    透過 Colab 批次下載 FreeTTS mp3

    2022年5月20日 星期五

    上一篇「雄 : 批次下載 FreeTTS mp3」談到以 wget、jq 和 Windows 的批次檔,將清單檔案中的英文,一行行解析後,到 FreeTTS 網站中合成 TTS 語音,並將 MP3 檔案下載回來。在那之前,其實已經先在 Google Colab 中,以 Python 寫了個「free-tts-mp3-dl.ipynb」的「筆記本」,測試過下載的程序。畢竟 Python 還是比較強大,此外, Colab 是在網頁瀏覽器中操作,環境比較單純,使用者不用再另外安裝別的工具,又可以跨平台使用,所以還是建議優先使用本篇的方法。

    Google Colab 中 free-tts-mp3-dl.ipynb 的共用網址如下:

    建立副本

    因為是用「檢視者」的方式共用的,所以如果有需要將自己的設定儲存,建議首次使用時,在雲端硬碟儲存複本,可以在開啟共用的網址後,找找上方有個「複製到雲端硬碟」的按鈕,然後按下去;或是按在主選單「檔案」中的「在雲端硬碟中儲存副本」。以後要用時,就可以開啟自己的 free-tts-mp3-dl。

    按「複製到雲端硬碟」建立副本

    下載 mp3 檔案

    在 Colab 中使用 free-tts-mp3-dl 批次下載 FreeTTS 的 mp3 檔案,只要三個步驟:

    • 設定 ttsVoiceName 指定要使用的 TTS 聲音。
    • 設定 textMessages 指定要下載的英文。
    • 按程式區塊左上角的 [播放] 鈕執行程式並等待結果。

    設定 ttsVoiceName 選擇聲音

    在 Free TTS 網站中, English (US) 的的聲音選單中有12個可以選擇,為了方便使用,我將它們的相關設定都預先建立好了,只要在 free-tts-mp3-dl 中找到「ttsVoiceName」這個變數後,將等號右邊,引號內的名稱字串換成想下載的即可選定。

    設定 ttsVoiceName 決定聲音

    可用的聲音名稱都列在註解中(井字號開頭,綠色的字),可供參考,並複製使用。

    設定 textMessages 

    free-tts-mp3-dl 會一行行分析 textMessages 變數中的文字;一行中,只會取出英文、空白、數字,遇到第一個非英文用的的符號即終止該行的分析。所以在 textMessages 中,可以直接貼入 HTML5 FUN 中使用到的英文相關題庫設定,或是單純的英文字串。

    下圖中,範例貼入的是 HTML5 FUN 單字高手/English1200 用的題庫 

    在 textMessages 中填入要下載的英文清單

    修改設定內容時,直接將上圖框框中的範例置換成想下載的英文,一行一個英文單字或句子。

    按「播放」執行下載程序

    在 Colab 中,每一個程式區塊(儲存格)的左上角會有一個「播放」鈕,按下去,就可以開始執行程式的功能。

    按「播放」鈕執行程式

    如果已經完成前兩步驟,設定完 ttsVoiceName 和 textMessages ,就可以按程式區塊左上角的「播放」鈕,開始分析哪些英文要下載 MP3 檔案,並送資料給 Free TTS 網站合成語音。下載回來的 MP3 檔案會暫存在您的 Colab 空間中,全部的 .mp3 檔案都由網站抓完了以後,會打包成一個 .zip 的壓縮檔,並自動下載到您的電腦中儲存。

    所以按完步驟 3 的播放鈕,就喝杯水,稍等一下囉!

    Q&A

    • Q : 一次可以下載多少個 MP3 檔案?
      A: 因為 FreeTTS 網站有防濫用的機置,建議不要一次下載太多個;分成多次完成,也可以比較善待這個好用的網站。
    • Q : 為什麼 MP3 檔案大小都是 0 ,無法播放 ?
      A : 會這樣子,有可能是 ttsVoiceName 設定錯誤(名稱必須完全一樣,多個空白都不行);或是 FreeTTS 網站有問題;再不然就是被 FreeTTS 防濫用,暫時鎖定不能使用了。
    • Q : 為什麼出現代碼 429 的訊息,無法下載到 .mp3 ?
      A : 可能一次下載太多,被 Free TTS 網站列入濫用名單了。

    相關文章


    2022年3月30日 星期三

    youtube-dl : 由 stdin 讀入網址

    2022年3月30日 星期三

    用 Python 寫了解析影片網址的小工具,網址要怎麼傳給 youtube-dl 呢?

    youtube-dl 有個參數 -a 或 --batch-file ,它可以用來指定讀取一個網址清單的檔案;清單檔案裡面,一行一個網址;讀取後,youtube-dl 會批次下載那些網址的影片。

    而 stdin / stdout 就像檔案一樣的操作,Python 以 print 將網址輸出,而 youtube-dl 就可以利用下面的語法來由 stdin 讀入

    youtube-dl  -a - 

    最後面那「-」減號就是 stdin。

    所以假設我的 Python 程式叫 parase.py,解析的網頁是 https://a.b.c.d/xxx.html ,要執行的指令就像這樣:

    python parse.py https://a.b.c.d/xxx.html | youtube-dl -a -

    其實也就好玩,玩一下,不然,應該是整個都用 Python 來寫就好,一支程式就能搞定,還能有更多的變化。


    Python : 錯誤訊息 : close failed in file object destructor

    用 Python 寫了一支解析網頁中網址的小工具,打算把網址丟給 youtube-dl 去下載。其實最後也不過用 print 輸出而已,在 shell 底下可以看到分析出的網址,但是 pipe 給 youtube-dl 後,卻出現了底下的訊息:

    close failed in file object destructor:
    sys.excepthook is missing
    lost sys.stderr

    查了一下,有 import sys ,在程式的最後面加入底下幾行,就不會冒出訊息了:

    try:
        sys.stdout.flush()
    except:
        pass
    try:
        sys.stdout.close()
    except:
        pass
    try:
        sys.stderr.close()
    except:
        pass



    2020年7月25日 星期六

    Inkscape : Raster 2 Laser GCode generator 除蟲

    2020年7月25日 星期六
    如果有在玩雷雕的話,Inkscape 的 extension Raster 2 Laser GCode generator 是很好用的工具。它可以先幫我們把 Inkscape 工作區中的圖形在背景下匯出成 PNG 格式的圖檔,然後再依使用者的設定,把每一個點的顏色(RGB)轉換為灰階(每一個點均用一個 0~255 的值來表示),最後再將灰階圖中的每一個點顏色轉換成 GCode 中雷射的強度。



    之前在測試 RGB 轉換為灰階的七個模式,其中的第一個名為「0.21R + 0.71G + 0.07B」,我一直覺得它哪裡怪怪的。假設別的模式花不到二十分鐘打雷射的圖形,它卻要花近兩個小時,看雷射移動的軌跡,它連不需要打雷射的地方(圖片中白色的部份)也打雷射,由輸出的 GCode 可以看到它第一個開啟雷射(M106   S3.0)的位置是在左下角的原點 (G00 X0.0 Y0.0 F1200),這很明顯和我設計的圖形是不同的。



     
    雄::gsyan © 2009. Design by Pocket