プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Windows 10 ファイル履歴の『古いバージョンのクリーンアップ』でエラーがでる件について

こちらの記事で書いたように、Windows 10 のファイル履歴機能を使って、バックアップを行っていました。

運用を始めたときに、バックアップ期間を3か月にしていたら、ディスク容量が足りなくなってきたので、詳細設定から『古いバージョンのクリーンアップ』を実行して、容量を開けようとしたら、こういうエラーがでてきました。

f:id:junichim:20211116154446p:plain

ん?なんでエラーになる?

と思い、調べてみると、類似の事例がいくつもあるようです。また、解決策もいろいろと提案されています。

これらに記載されている解決策をいろいろと試してみたのですが、残念ながら解決できませんでした。

結論

結局、ファイル履歴で古いバージョンのクリーンアップを実行してエラーがでるのは解決できませんでした。となると、

ディスクフルになるまで、ファイル履歴とって、容量がいっぱいになったら、手作業で消して、再度セットアップして・・・

という運用も不可能ではありませんが、まあ、やりたくないですね。

ということで、残念ながらファイル履歴を使うのは諦めます。

で、バックアップをどうするかですが、 wsl2 があるので、 rsync を動かせば対応できるのではないかと思ってます。これについては別途試してみます。

参考1

なお、ファイル履歴の設定やテストを行っているときに、詳細設定の画面で、

f:id:junichim:20211228214514p:plain

というメッセージがでていることに気が付きました。

これって何だろうと調べてみると、似たような話題の記事もありました。

山市良のえぬなんとかわーるど: Windows 8.1 のファイルの履歴の気になる日本語メッセージ

(直接言及はされていませんが)上記の記事を読んでいて、ひょっとして、Dドライブを、junctionとして割り当ててる影響かと思い、一時的に解除してから、再起動したら、メッセージが消えていました。

f:id:junichim:20211228215323p:plain

たぶん、これが原因ですね。ご参考までに。

参考2

ファイル履歴は一度停止して、保存先のドライブを再セットアップすると、フォルダ構成などがリセットされます。 これ、手作業で再設定するの結構手間がかかります。

今回は試していませんが、それへの対応方法もあるようです。

windows-10 — Win10 :(構成を維持しながら)ファイル履歴をリセットする方法

うまくいけば、セットアップが簡単になりますね。

ご参考までに。

QuFirewall の日本語表示

QNAP の QTS 5.0.0 にアップデートしたあとだったと思いますが、デフォルトで、 Security Counselor というのが動作するようになったようです。 それを使うと、セキュリティ関係の情報をまとめて確認できるのですが、その項目の一つに、 QuFirewall というのがあります。要は QNAP 上の Firewall ですね。

今まで使ってなかったので、今回それをインストールしてみました。

インストールは簡単で App Center からインストールすればOKです。

インストール後、最初に起動する際に、いろいろと設定を聞かれます。基本的には公式サイトの説明通りなので、省略します。

で、インストールして、 QuFirewall が使えるとなったのですが、画面が英語表記のままです。

f:id:junichim:20211214120217p:plain

App Center の表示だと、対応言語に

f:id:junichim:20211214121212p:plain

日本語が含まれているのですが、謎です。設定項目を見ても言語設定などはありません。

困ったなと思い、QNAPに問い合わせると、QTS自体の言語設定を『日本語』にしてください、とのことです。

確認してみると、今までは『自動検出』でした。

f:id:junichim:20211214115939p:plain

これを『日本語』に変更

f:id:junichim:20211214120031p:plain

してから、QuFirewall を起動すると、問題なく日本語で表示されました。

f:id:junichim:20211214120124p:plain

QuFirewall 側が自動検出に対応していなかったというオチのようです。

Python で text-to-speach を試してみる

先日の記事で、古いノートPCを復活させた話を書きましたが、早速使う時がきました。

伊勢市内の中学校を対象に、キャリア教育の一環として、市内の事業者などの有志が仕事の話をするビジネスパーク伊勢というのがあって、私も都合が合う時にたまに参加しています。

コロナが落ち着いたこともあり、先日、対面式で再開され、その際にプログラマーの仕事について話す機会がありました。 で、せっかくなのでデモがてら、こんなことできるよ、という紹介の一つとして、 python での text-to-speech を実演してきました。

その際に行ったセットアップなどについて、まとめておきます。

実行環境は次の通りです。

  • Lubuntu 18.04.6, 32bit 版
  • python 3.6.9
  • pip3 9.0.1

pyttsx3 のインストール

python で text-to-speech をするには pyttsx3 をつかうと簡単にできることを知りました(cs50.jp 見てたら出てきたので、さっそく使わせてもらいました)。このライブラリって、オフラインで動くんですよね、すげー。

まずは pip3 と pyttsx3 をインストールします。

mor@Lenovo3000:~$ sudp apt install python3-pip
mor@Lenovo3000:~$ pip3 install pyttsx3

使ってみます。

mor@Lenovo3000:~$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyttsx3
>>> engine = pyttsx3.init()
Traceback (most recent call last):
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/__init__.py", line 20, in init
    eng = _activeEngines[driverName]
  File "/usr/lib/python3.6/weakref.py", line 137, in __getitem__
    o = self.data[key]()
KeyError: None

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/__init__.py", line 22, in init
    eng = Engine(driverName, debug)
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/engine.py", line 30, in __init__
    self.proxy = driver.DriverProxy(weakref.proxy(self), driverName, debug)
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/driver.py", line 50, in __init__
    self._module = importlib.import_module(name)
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/drivers/espeak.py", line 9, in <module>
    from . import _espeak, toUtf8, fromUtf8
  File "/home/mor/.local/lib/python3.6/site-packages/pyttsx3/drivers/_espeak.py", line 18, in <module>
    dll = cdll.LoadLibrary('libespeak.so.1')
  File "/usr/lib/python3.6/ctypes/__init__.py", line 426, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python3.6/ctypes/__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libespeak.so.1: cannot open shared object file: No such file or directory
>>> 

あれ?初期化しただけなのにエラーになりました。

ちょっとネットを調べてみると、 Linux の場合、 espeak というパッケージがないとだめなようです。

なので、必要なパッケージをインストールします。

mor@Lenovo3000:~$ sudo apt install espeak
mor@Lenovo3000:~$ sudo apt install ffmpeg

libespeak1 は espeak を入れると入るようです。

もう一度試すと

mor@Lenovo3000:~/work$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyttsx3
>>> engine = pyttsx3.init()
>>> engine.say("hello world")
>>> engine.runAndWait()
>>> 

ちゃんと聞こえますね。これ、結構楽しいですね。

英語だけだとなんなので、日本語も試してみます。

>>> 
>>> engine.say("こんにちは")
>>> engine.runAndWait()
>>> 

あれ?日本語だと使えないですね。

日本語への対応

調べてみると、

python - Pyttsx3 does not read text in other languages - Stack Overflow

言語設定を調べて、切り替える必要があるようです。確認してみます。

こんな内容の test_tts.py を作ります。

import pyttsx3

engine = pyttsx3.init()
voices = engine.getProperty('voices')
for voice in voices:
    print(f"Voice: {voice.name}")

これを実行してみます。

mor@Lenovo3000:~/work$ python3 test_tts.py 
Voice: afrikaans
Voice: aragonese
Voice: bulgarian
Voice: bosnian
Voice: catalan
Voice: czech
Voice: welsh
Voice: danish
Voice: german
Voice: greek
Voice: default
Voice: english
Voice: en-scottish
Voice: english-north
Voice: english_rp
Voice: english_wmids
Voice: english-us
Voice: en-westindies
Voice: esperanto
Voice: spanish
Voice: spanish-latin-am
Voice: estonian
Voice: persian
Voice: persian-pinglish
Voice: finnish
Voice: french-Belgium
Voice: french
Voice: irish-gaeilge
Voice: greek-ancient
Voice: hindi
Voice: croatian
Voice: hungarian
Voice: armenian
Voice: armenian-west
Voice: indonesian
Voice: icelandic
Voice: italian
Voice: lojban
Voice: georgian
Voice: kannada
Voice: kurdish
Voice: latin
Voice: lingua_franca_nova
Voice: lithuanian
Voice: latvian
Voice: macedonian
Voice: malayalam
Voice: malay
Voice: nepali
Voice: dutch
Voice: norwegian
Voice: punjabi
Voice: polish
Voice: brazil
Voice: portugal
Voice: romanian
Voice: russian
Voice: slovak
Voice: albanian
Voice: serbian
Voice: swedish
Voice: swahili-test
Voice: tamil
Voice: turkish
Voice: vietnam
Voice: vietnam_hue
Voice: vietnam_sgn
Voice: Mandarin
Voice: cantonese
mor@Lenovo3000:~/work$ 

まじですか。確かに、日本語が入っていないです。

もう少し調べてみると、 espeak で対応していない言語も espeak-ng だとカバーされている場合があるとのことです。

なので、下記記事を参考に espeak-ng に切り替えてみます。

Is there a way to use the espeak-ng engine? · Issue #103 · nateshmbhat/pyttsx3 · GitHub

mor@Lenovo3000:~/work$ sudo apt purge espeak
mor@Lenovo3000:~/work$ sudo apt autoremove
mor@Lenovo3000:~/work$ sudo apt install espeak-ng
mor@Lenovo3000:~/work$ cd /usr/lib/i386-linux-gnu/
mor@Lenovo3000:/usr/lib/i386-linux-gnu$ sudo ln -s libespeak-ng.so.1 libespeak.so.1

espeak (および libespeak1 )をアンインストールして、espeak-ng を入れて、libespeak-ng.so.1 にシンボリックリンクを張ればよいようです。 そのうえで、しゃべる前に、前述の記事にあったように setProperty で言語を指定すればよいようです。

試してみます。

mor@Lenovo3000:~/work$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyttsx3
>>> engine = pyttsx3.init()
>>> engine.setProperty("voice", "Japanese")
>>> engine.say("こんにちは")
>>> engine.runAndWait()

おお、日本語でしゃべれますね。

ただ、漢字は読めずに、ひらがなでないとダメとか、文がながいと途端に聞き取りにくくなるとか、微妙な点もあるけど、まずもって動くのはいいですね。

まとめ

冒頭の出前授業でも無事に text-to-speach を見せることができました。デモ的には、

import pyttsx3

engine = pyttsx3.init()

engine.setProperty("voice", "Japanese")

#rate = engine.getProperty("rate")
#print(f"rate: {rate}")
engine.setProperty("rate", 130)

while (1):
    txt = input("ひらがなで文字をにゅうりょくしてください: ")

    #print(f"text is: [{txt}]")
    if txt == None or len(txt) == 0:
        exit()
    engine.say(txt)
    engine.runAndWait()

上記のように、コマンドラインで入力した文言をそのまま音声で読む形にしました。機械的な合成音が面白いようで、ややうけ、という感じでした。

ちなみに、 Scratch でネコを動かしたほうがウケていたのは、内緒にしておいてください。恐るべし、 Scratch 。