mirror of https://gitlab.com/gpvkt/twitchtts.git
rebase
This commit is contained in:
parent
7d2a85173a
commit
771be01850
286
CHANGELOG.md
286
CHANGELOG.md
|
@ -1,143 +1,143 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. If there is a `Changed` section please read carefully, as this often means that you will need to adapt your `config.yml`, otherwise the bot might fail to start.
|
All notable changes to this project will be documented in this file. If there is a `Changed` section please read carefully, as this often means that you will need to adapt your `config.yml`, otherwise the bot might fail to start.
|
||||||
|
|
||||||
## [1.6.1] - 2022-08-25
|
## [1.6.1] - 2022-08-25
|
||||||
|
|
||||||
### Fixed 1.6.1
|
### Fixed 1.6.1
|
||||||
|
|
||||||
* Type Error during pick
|
* Type Error during pick
|
||||||
* Improved command handling
|
* Improved command handling
|
||||||
|
|
||||||
## [1.6.0] - 2022-08-25
|
## [1.6.0] - 2022-08-25
|
||||||
|
|
||||||
### Added 1.6.0
|
### Added 1.6.0
|
||||||
|
|
||||||
* `!pick` command
|
* `!pick` command
|
||||||
|
|
||||||
## [1.5.0] - 2022-08-24
|
## [1.5.0] - 2022-08-24
|
||||||
|
|
||||||
### Added 1.5.0
|
### Added 1.5.0
|
||||||
|
|
||||||
* `!wiki` command
|
* `!wiki` command
|
||||||
* `!version` command
|
* `!version` command
|
||||||
|
|
||||||
### Changed 1.5.0
|
### Changed 1.5.0
|
||||||
|
|
||||||
* Added `!sq` as alias for `!smartquote`
|
* Added `!sq` as alias for `!smartquote`
|
||||||
|
|
||||||
### Fixed 1.5.0
|
### Fixed 1.5.0
|
||||||
|
|
||||||
* Darkmode: Options background color
|
* Darkmode: Options background color
|
||||||
|
|
||||||
## [1.4.0] - 2022-08-23
|
## [1.4.0] - 2022-08-23
|
||||||
|
|
||||||
### Added 1.4.0
|
### Added 1.4.0
|
||||||
|
|
||||||
* `!usermap` command added
|
* `!usermap` command added
|
||||||
* `!delay` command added
|
* `!delay` command added
|
||||||
* Darkmode added
|
* Darkmode added
|
||||||
|
|
||||||
## [1.3.2] - 2022-08-19
|
## [1.3.2] - 2022-08-19
|
||||||
|
|
||||||
### Fixed 1.3.2
|
### Fixed 1.3.2
|
||||||
|
|
||||||
* `!smartquote` and `!addquote` are not longer Mods only.
|
* `!smartquote` and `!addquote` are not longer Mods only.
|
||||||
|
|
||||||
## [1.3.1] - 2022-08-19
|
## [1.3.1] - 2022-08-19
|
||||||
|
|
||||||
### Added 1.3.1
|
### Added 1.3.1
|
||||||
|
|
||||||
* Added `game_name` and date to quote
|
* Added `game_name` and date to quote
|
||||||
|
|
||||||
### Fixed (hopefully) 1.3.1
|
### Fixed (hopefully) 1.3.1
|
||||||
|
|
||||||
* Improved HTTP request handling (hopefully removes delay in Chrome)
|
* Improved HTTP request handling (hopefully removes delay in Chrome)
|
||||||
|
|
||||||
## [1.3.0] - 2022-08-18
|
## [1.3.0] - 2022-08-18
|
||||||
|
|
||||||
### Added 1.3.0
|
### Added 1.3.0
|
||||||
|
|
||||||
* Added `!smartquote` command
|
* Added `!smartquote` command
|
||||||
* Added `!addquote` command
|
* Added `!addquote` command
|
||||||
|
|
||||||
## [1.2.5] - 2022-08-16
|
## [1.2.5] - 2022-08-16
|
||||||
|
|
||||||
### Changed 1.2.5
|
### Changed 1.2.5
|
||||||
|
|
||||||
* Improved logging
|
* Improved logging
|
||||||
|
|
||||||
## [1.2.4] - 2022-08-15
|
## [1.2.4] - 2022-08-15
|
||||||
|
|
||||||
### Added 1.2.4
|
### Added 1.2.4
|
||||||
|
|
||||||
* Check OAuth Token via Twitch API
|
* Check OAuth Token via Twitch API
|
||||||
|
|
||||||
### Fixed 1.2.4
|
### Fixed 1.2.4
|
||||||
|
|
||||||
* Internal URL when using special HTTP_BIND values
|
* Internal URL when using special HTTP_BIND values
|
||||||
|
|
||||||
## [1.2.3] - 2022-08-14
|
## [1.2.3] - 2022-08-14
|
||||||
|
|
||||||
### Fixed 1.2.3
|
### Fixed 1.2.3
|
||||||
|
|
||||||
* Message sort order
|
* Message sort order
|
||||||
|
|
||||||
## [1.2.2] - 2022-08-13
|
## [1.2.2] - 2022-08-13
|
||||||
|
|
||||||
### Changed 1.2.2
|
### Changed 1.2.2
|
||||||
|
|
||||||
* The message queue is only queried when the Init button is pressed
|
* The message queue is only queried when the Init button is pressed
|
||||||
* Further code optimization
|
* Further code optimization
|
||||||
|
|
||||||
### Fixed 1.2.2
|
### Fixed 1.2.2
|
||||||
|
|
||||||
* Minor fixes
|
* Minor fixes
|
||||||
|
|
||||||
## [1.2.1] - 2022-08-13
|
## [1.2.1] - 2022-08-13
|
||||||
|
|
||||||
### Changed 1.2.1
|
### Changed 1.2.1
|
||||||
|
|
||||||
* Reworked internal code structure
|
* Reworked internal code structure
|
||||||
|
|
||||||
### Fixed 1.2.1
|
### Fixed 1.2.1
|
||||||
|
|
||||||
* Publish vote info in chat when reloading config was not working when TTS was disabled
|
* Publish vote info in chat when reloading config was not working when TTS was disabled
|
||||||
* Casting votes was allowed for broadcaster and mods only
|
* Casting votes was allowed for broadcaster and mods only
|
||||||
|
|
||||||
## [1.2.0] - 2022-08-13
|
## [1.2.0] - 2022-08-13
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* `!random` feature (see README.md for details)
|
* `!random` feature (see README.md for details)
|
||||||
|
|
||||||
### Changed 1.2.0
|
### Changed 1.2.0
|
||||||
|
|
||||||
* The vote result will be read out
|
* The vote result will be read out
|
||||||
|
|
||||||
### Fixed 1.2.0
|
### Fixed 1.2.0
|
||||||
|
|
||||||
* Improved handling of missing config values
|
* Improved handling of missing config values
|
||||||
|
|
||||||
## [1.1.0] - 2022-08-12
|
## [1.1.0] - 2022-08-12
|
||||||
|
|
||||||
### Added 1.1.0
|
### Added 1.1.0
|
||||||
|
|
||||||
* `!quickvote` feature (see README.md for details)
|
* `!quickvote` feature (see README.md for details)
|
||||||
* `!ping` command added
|
* `!ping` command added
|
||||||
* Configoption to start TTS in disabled mode
|
* Configoption to start TTS in disabled mode
|
||||||
* OAuth-Token generator
|
* OAuth-Token generator
|
||||||
* Webbrowser autostart
|
* Webbrowser autostart
|
||||||
|
|
||||||
### Changed 1.1.0
|
### Changed 1.1.0
|
||||||
|
|
||||||
* You need to review your `config.yml` as there a new config values added.
|
* You need to review your `config.yml` as there a new config values added.
|
||||||
* The bot replies with a chat message when `!ton` or `!toff` is used
|
* The bot replies with a chat message when `!ton` or `!toff` is used
|
||||||
|
|
||||||
### Fixed 1.1.0
|
### Fixed 1.1.0
|
||||||
|
|
||||||
* Improved error handling
|
* Improved error handling
|
||||||
|
|
||||||
## [1.0.0] - 2022-08-11
|
## [1.0.0] - 2022-08-11
|
||||||
|
|
||||||
Initial Release
|
Initial Release
|
||||||
|
|
740
README.md
740
README.md
|
@ -1,370 +1,370 @@
|
||||||
# Twitch TextToSpeech Bot
|
# Twitch TextToSpeech Bot
|
||||||
|
|
||||||
![Latest Release](https://img.shields.io/gitlab/v/release/38486705) ![License](https://img.shields.io/gitlab/license/38486705) ![Maintenance](https://img.shields.io/maintenance/yes/2022)
|
![Latest Release](https://img.shields.io/gitlab/v/release/38486705) ![License](https://img.shields.io/gitlab/license/38486705) ![Maintenance](https://img.shields.io/maintenance/yes/2022)
|
||||||
|
|
||||||
A simple Twitch TTS bot (Web Speech API)
|
A simple Twitch TTS bot (Web Speech API)
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
The goal of this project is to provide a simple to use Text to Speech IRC bot. It's mainly focused on Twitch, but might be easily adapt to other IRC chats as well. Anyway, right now some parts are Twitch specific (like `CAP REQ :twitch.tv/commands twitch.tv/tags`). There are some other projects providing TTS for IRC based chats, like [IRC Radio (TTS)](https://play.google.com/store/apps/details?id=com.earthflare.android.ircradio&hl=en&gl=US), but they often are missing moderation features like Black-/Whitelists or deletion of single messages, before they are read. Therefore I created my own TTS bot, providing those features. Another very important aspect was that you should use almost any device capable running an HTML5-webbrowser as output. Therefore the bot uses a client-server "architecture". You can run the bot - for example - on your IRL server, but use your phone as output device. A mobile only solution always have the disadvantage of loosing messages, e.g. when your mobile connection drops.
|
The goal of this project is to provide a simple to use Text to Speech IRC bot. It's mainly focused on Twitch, but might be easily adapt to other IRC chats as well. Anyway, right now some parts are Twitch specific (like `CAP REQ :twitch.tv/commands twitch.tv/tags`). There are some other projects providing TTS for IRC based chats, like [IRC Radio (TTS)](https://play.google.com/store/apps/details?id=com.earthflare.android.ircradio&hl=en&gl=US), but they often are missing moderation features like Black-/Whitelists or deletion of single messages, before they are read. Therefore I created my own TTS bot, providing those features. Another very important aspect was that you should use almost any device capable running an HTML5-webbrowser as output. Therefore the bot uses a client-server "architecture". You can run the bot - for example - on your IRL server, but use your phone as output device. A mobile only solution always have the disadvantage of loosing messages, e.g. when your mobile connection drops.
|
||||||
|
|
||||||
The project consits of a very simple IRC client, which monitors the incoming messages. If a valid⃰ `!tts` command is detected the message will send into a queue. Depending on your config it will wait there a few seconds for deletion by you/your moderators. If nobody deletes the message, it will send into another queue. This queue will get fetched by the HTML frontend, which will be delivered by an internal webserver (backend). The HTML frontend will use the [Web Speech API](https://wicg.github.io/speech-api/) included in any modern webbrowser to read the incoming TTS message. When this is done it will report back to the webserver and the message will be removed from the queue.
|
The project consits of a very simple IRC client, which monitors the incoming messages. If a valid⃰ `!tts` command is detected the message will send into a queue. Depending on your config it will wait there a few seconds for deletion by you/your moderators. If nobody deletes the message, it will send into another queue. This queue will get fetched by the HTML frontend, which will be delivered by an internal webserver (backend). The HTML frontend will use the [Web Speech API](https://wicg.github.io/speech-api/) included in any modern webbrowser to read the incoming TTS message. When this is done it will report back to the webserver and the message will be removed from the queue.
|
||||||
|
|
||||||
The server part is written in Python. The TTS part is written in Javascript.
|
The server part is written in Python. The TTS part is written in Javascript.
|
||||||
|
|
||||||
By using Javascript for the actual TTS part it's not only very easy to access the Web Speech API and the underlying Speech features of your OS, it also makes it possible to use a wide range of devices to actually play the TTS output. You can start the backend on your PC/Server and open the frontend on your Android/iOS tablet or Mobile Phone. If you expose the backend to the internet (I would recommend to use a reverse proxy, rather than exposing the backend directly) you can also use the TTS bot on the go (e.g. your IRL setup).
|
By using Javascript for the actual TTS part it's not only very easy to access the Web Speech API and the underlying Speech features of your OS, it also makes it possible to use a wide range of devices to actually play the TTS output. You can start the backend on your PC/Server and open the frontend on your Android/iOS tablet or Mobile Phone. If you expose the backend to the internet (I would recommend to use a reverse proxy, rather than exposing the backend directly) you can also use the TTS bot on the go (e.g. your IRL setup).
|
||||||
|
|
||||||
(⃰sender is not on the blacklist, message is not too long, etc.)
|
(⃰sender is not on the blacklist, message is not too long, etc.)
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
* Browser with Web Speech API support
|
* Browser with Web Speech API support
|
||||||
* Web Speech API Voices (usually already included in your OS and/or browser)
|
* Web Speech API Voices (usually already included in your OS and/or browser)
|
||||||
* If you use `tts.py` see `requirements.txt`. If you use `tts.exe` all dependencies are included.
|
* If you use `tts.py` see `requirements.txt`. If you use `tts.exe` all dependencies are included.
|
||||||
|
|
||||||
### Installing
|
### Installing
|
||||||
|
|
||||||
1. Clone the repo, or download and unzip the newest [Release](https://gitlab.com/gpvkt/twitchtts/-/releases)
|
1. Clone the repo, or download and unzip the newest [Release](https://gitlab.com/gpvkt/twitchtts/-/releases)
|
||||||
2. Rename/copy `config-dist.yml` to `config.yml`
|
2. Rename/copy `config-dist.yml` to `config.yml`
|
||||||
3. Adapt `config.yml` to your needs. See `Configuration` for details.
|
3. Adapt `config.yml` to your needs. See `Configuration` for details.
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Please use `UTF-8` as encoding, when editing `config.yml`.
|
Please use `UTF-8` as encoding, when editing `config.yml`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
``` lang=yaml
|
``` lang=yaml
|
||||||
irc:
|
irc:
|
||||||
channel: "#gpkvt"
|
channel: "#gpkvt"
|
||||||
username: "ttsbot"
|
username: "ttsbot"
|
||||||
oauth_token: "oauth:ohkoace0wooghue8she9xaN0nooSau"
|
oauth_token: "oauth:ohkoace0wooghue8she9xaN0nooSau"
|
||||||
server: "irc.chat.twitch.tv"
|
server: "irc.chat.twitch.tv"
|
||||||
clearmsg_timeout: 10
|
clearmsg_timeout: 10
|
||||||
|
|
||||||
http:
|
http:
|
||||||
port: 80
|
port: 80
|
||||||
bind: "localhost"
|
bind: "localhost"
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
start_enabled: True
|
start_enabled: True
|
||||||
subonly: False
|
subonly: False
|
||||||
modonly: False
|
modonly: False
|
||||||
message_length: 200
|
message_length: 200
|
||||||
language: de
|
language: de
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
toff: "TTS is now inactive."
|
toff: "TTS is now inactive."
|
||||||
ton: "TTS is now active."
|
ton: "TTS is now active."
|
||||||
too_long: "Sorry, your TTS message is too long."
|
too_long: "Sorry, your TTS message is too long."
|
||||||
disabled: "Sorry, TTS is disabled right now."
|
disabled: "Sorry, TTS is disabled right now."
|
||||||
denied: "Sorry, you are not allowed to use TTS."
|
denied: "Sorry, you are not allowed to use TTS."
|
||||||
subonly: "Sorry, TTS is a sub-only feature."
|
subonly: "Sorry, TTS is a sub-only feature."
|
||||||
whitelist: "Sorry, you are not allowed to use TTS."
|
whitelist: "Sorry, you are not allowed to use TTS."
|
||||||
ready: "TTS bot alpha ready!"
|
ready: "TTS bot alpha ready!"
|
||||||
says: "says"
|
says: "says"
|
||||||
votestart: "Quickvote started. Send #yourchoice to participate."
|
votestart: "Quickvote started. Send #yourchoice to participate."
|
||||||
voteend: "Quickvote ended. The results are:"
|
voteend: "Quickvote ended. The results are:"
|
||||||
votenobody: "Nobody casted a vote. :("
|
votenobody: "Nobody casted a vote. :("
|
||||||
voteresult: "Voting has ended. The result is:"
|
voteresult: "Voting has ended. The result is:"
|
||||||
votes: "Votes"
|
votes: "Votes"
|
||||||
pickstart: "Pick started. Send #pickme to participate."
|
pickstart: "Pick started. Send #pickme to participate."
|
||||||
pickresult: "Pick ended. The results are:"
|
pickresult: "Pick ended. The results are:"
|
||||||
picknone: "Nobody was picked. :("
|
picknone: "Nobody was picked. :("
|
||||||
quotenotfound: "Sorry, no quote found."
|
quotenotfound: "Sorry, no quote found."
|
||||||
quoteaddedprefix: "Quote:"
|
quoteaddedprefix: "Quote:"
|
||||||
quoteaddedsuffix: "added."
|
quoteaddedsuffix: "added."
|
||||||
wiki_too_many: "Sorry, there are too many possible results. Try a more narrow search."
|
wiki_too_many: "Sorry, there are too many possible results. Try a more narrow search."
|
||||||
wiki_no_result: "Sorry, there was an error fetching the wikipedia answer."
|
wiki_no_result: "Sorry, there was an error fetching the wikipedia answer."
|
||||||
|
|
||||||
log:
|
log:
|
||||||
level: "INFO"
|
level: "INFO"
|
||||||
|
|
||||||
usermapping:
|
usermapping:
|
||||||
gpkvt: "gpk"
|
gpkvt: "gpk"
|
||||||
|
|
||||||
whitelist:
|
whitelist:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Explanation
|
#### Explanation
|
||||||
|
|
||||||
##### irc
|
##### irc
|
||||||
|
|
||||||
* `channel`: Channel you want to monitor (e.g. #gpkvt)
|
* `channel`: Channel you want to monitor (e.g. #gpkvt)
|
||||||
* `username`: The bots username (e.g. gpkvt)
|
* `username`: The bots username (e.g. gpkvt)
|
||||||
* `oauth_token`: The bots OAUTH-Token (e.g. oauth:ohkoace0wooghue8she9xaN0nooSau)
|
* `oauth_token`: The bots OAUTH-Token (e.g. oauth:ohkoace0wooghue8she9xaN0nooSau)
|
||||||
* `server`: Twitch IRC server to be used (default should be fine)
|
* `server`: Twitch IRC server to be used (default should be fine)
|
||||||
* `clearmsg_timeout`: Time to wait for an moderator to delete a message, before it's added to the TTS queue
|
* `clearmsg_timeout`: Time to wait for an moderator to delete a message, before it's added to the TTS queue
|
||||||
|
|
||||||
You can generate your `oauth_token` by leaving the value empty when starting `tts.exe/tts.py`. The integrated webserver will then provide an OAuth-Generator. Due to limitations to the `redirect_url` parameter used by twitch, this is only possible if you use Port `8080` or `80` as `http:bind`. If you use a different port, you will need to use another [Twitch OAuth Generator](https://html.duckduckgo.com/html/?q=twitch+oauth+token+generator). The bot will need `chat:edit` and `chat:read` permissions.
|
You can generate your `oauth_token` by leaving the value empty when starting `tts.exe/tts.py`. The integrated webserver will then provide an OAuth-Generator. Due to limitations to the `redirect_url` parameter used by twitch, this is only possible if you use Port `8080` or `80` as `http:bind`. If you use a different port, you will need to use another [Twitch OAuth Generator](https://html.duckduckgo.com/html/?q=twitch+oauth+token+generator). The bot will need `chat:edit` and `chat:read` permissions.
|
||||||
|
|
||||||
Please note that the `oauth_token` is valid for approximately 60 days. If it become invalid the bot will not connect anymore and you will have to renew the token.
|
Please note that the `oauth_token` is valid for approximately 60 days. If it become invalid the bot will not connect anymore and you will have to renew the token.
|
||||||
|
|
||||||
##### http
|
##### http
|
||||||
|
|
||||||
* `port`: Internal Webserver Port to listen to (e.g. 8080)
|
* `port`: Internal Webserver Port to listen to (e.g. 8080)
|
||||||
* `bind`: Interface/IP to bind server to (e.g. localhost)
|
* `bind`: Interface/IP to bind server to (e.g. localhost)
|
||||||
|
|
||||||
##### bot
|
##### bot
|
||||||
|
|
||||||
* `start_enabled`: Enable the bot on start? If `False` you need to use `!ton` first to make TTS work.
|
* `start_enabled`: Enable the bot on start? If `False` you need to use `!ton` first to make TTS work.
|
||||||
* `subonly`: If `True` only Subs can use TTS
|
* `subonly`: If `True` only Subs can use TTS
|
||||||
* `modonly`: If `True` only Mods can use TTS
|
* `modonly`: If `True` only Mods can use TTS
|
||||||
* `message_length`: Maximum allowed message length for TTS
|
* `message_length`: Maximum allowed message length for TTS
|
||||||
* `language`: Language for `!wiki` command
|
* `language`: Language for `!wiki` command
|
||||||
|
|
||||||
##### messages
|
##### messages
|
||||||
|
|
||||||
* `toff`: The bots reply when `!toff` is used.
|
* `toff`: The bots reply when `!toff` is used.
|
||||||
* `ton`: The bots reply when `!ton` is used.
|
* `ton`: The bots reply when `!ton` is used.
|
||||||
* `too_long`: The bots reply if message exceeds `message_length`
|
* `too_long`: The bots reply if message exceeds `message_length`
|
||||||
* `disabled`: The bots reply if TTS is disabled
|
* `disabled`: The bots reply if TTS is disabled
|
||||||
* `denied`: The bots reply if the user is not allowed to use TTS
|
* `denied`: The bots reply if the user is not allowed to use TTS
|
||||||
* `subonly`: The bots reply if `subonly` is active and the user isn't one.
|
* `subonly`: The bots reply if `subonly` is active and the user isn't one.
|
||||||
* `whitelist`: The bots reply if `whitelist` is set and user isn't on the list.
|
* `whitelist`: The bots reply if `whitelist` is set and user isn't on the list.
|
||||||
* `ready`: The bots init message
|
* `ready`: The bots init message
|
||||||
* `says`: Prefix to add between username and message
|
* `says`: Prefix to add between username and message
|
||||||
* `votestart`: Message when a quickvote was started.
|
* `votestart`: Message when a quickvote was started.
|
||||||
* `voteend`: Message when a quickvote ends.
|
* `voteend`: Message when a quickvote ends.
|
||||||
* `votenobody`: Message when quickvote ends, but nobody has voted.
|
* `votenobody`: Message when quickvote ends, but nobody has voted.
|
||||||
* `voteresult`: Prefix for the result (will be read out).
|
* `voteresult`: Prefix for the result (will be read out).
|
||||||
* `votes`: Suffix to vote count.
|
* `votes`: Suffix to vote count.
|
||||||
* `pickstart`: Message when `!pick` was started.
|
* `pickstart`: Message when `!pick` was started.
|
||||||
* `pickresult`: Message when `!pick` ends.
|
* `pickresult`: Message when `!pick` ends.
|
||||||
* `picknone`: Message if nobody was picked.
|
* `picknone`: Message if nobody was picked.
|
||||||
* `quotenotfound`: Message if requests quote wasn't found.
|
* `quotenotfound`: Message if requests quote wasn't found.
|
||||||
* `quoteaddedprefix`: Prefix for `Quote <number> added` message.
|
* `quoteaddedprefix`: Prefix for `Quote <number> added` message.
|
||||||
* `quoteaddedsuffix`: Suffix for `Quote <number> added` message.
|
* `quoteaddedsuffix`: Suffix for `Quote <number> added` message.
|
||||||
* `wiki_too_many`: Message if `!wiki` command has more than one result.
|
* `wiki_too_many`: Message if `!wiki` command has more than one result.
|
||||||
* `wiki_no_result`: Message if `!wiki` command hasn't a valid result.
|
* `wiki_no_result`: Message if `!wiki` command hasn't a valid result.
|
||||||
|
|
||||||
##### log
|
##### log
|
||||||
|
|
||||||
* `level`: The loglevel, valid values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
* `level`: The loglevel, valid values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`
|
||||||
|
|
||||||
Do not use `DEBUG` in a production environment.
|
Do not use `DEBUG` in a production environment.
|
||||||
|
|
||||||
##### usermapping
|
##### usermapping
|
||||||
|
|
||||||
Use this section to define key:value pairs of usernames. The first value is the Twitch username, the second value is how the bot should pronouce the user, when reading the message. This is helpfull if you have regulars with numbers or strangs chars in the name. You can add new/change entries on the fly without restarting the bot (changes took up to 60 seconds).
|
Use this section to define key:value pairs of usernames. The first value is the Twitch username, the second value is how the bot should pronouce the user, when reading the message. This is helpfull if you have regulars with numbers or strangs chars in the name. You can add new/change entries on the fly without restarting the bot (changes took up to 60 seconds).
|
||||||
|
|
||||||
Please note: The key (real username) MUST be lowercase.
|
Please note: The key (real username) MUST be lowercase.
|
||||||
|
|
||||||
##### whitelist
|
##### whitelist
|
||||||
|
|
||||||
You can add a whitelist section to `config.yml`, a whitelist will override any other settings like `subonly` and `modonly`. Only users on the whitelist are allowed to use `!tts`. Broadcasters and mods can temporarily add users (including themselfs) to the whitelist by using the `!ptts` command, though.
|
You can add a whitelist section to `config.yml`, a whitelist will override any other settings like `subonly` and `modonly`. Only users on the whitelist are allowed to use `!tts`. Broadcasters and mods can temporarily add users (including themselfs) to the whitelist by using the `!ptts` command, though.
|
||||||
|
|
||||||
A whitelist looks as follows:
|
A whitelist looks as follows:
|
||||||
|
|
||||||
``` lang=yaml
|
``` lang=yaml
|
||||||
whitelist:
|
whitelist:
|
||||||
- gpkvt
|
- gpkvt
|
||||||
- foo
|
- foo
|
||||||
- bar
|
- bar
|
||||||
```
|
```
|
||||||
|
|
||||||
To disable the whitelist, remove it from `config.yml` completely. If you just leave `whitelist:` without entries, everyone must be whitelisted using `!ptts` (even broadcaster and mods). The permit is temporary until the bot restarts or (whichever happens first) if the user is removed from the whitelist using `!dtts`.
|
To disable the whitelist, remove it from `config.yml` completely. If you just leave `whitelist:` without entries, everyone must be whitelisted using `!ptts` (even broadcaster and mods). The permit is temporary until the bot restarts or (whichever happens first) if the user is removed from the whitelist using `!dtts`.
|
||||||
|
|
||||||
Please note: Usernames MUST be lowercase.
|
Please note: Usernames MUST be lowercase.
|
||||||
|
|
||||||
### Executing program
|
### Executing program
|
||||||
|
|
||||||
Execute `tts.exe` (or `tts.py` if you have Python installed), open the TTS webpage in your browser (the URL depends on your `bind` and `port` configuration, usually it's just `http://localhost`). Click the `Init` button at the button of the TTS webpage (you should hear `Init complete`).
|
Execute `tts.exe` (or `tts.py` if you have Python installed), open the TTS webpage in your browser (the URL depends on your `bind` and `port` configuration, usually it's just `http://localhost`). Click the `Init` button at the button of the TTS webpage (you should hear `Init complete`).
|
||||||
|
|
||||||
Connect to the configured Twitch channel and send a message starting with `!tts`. After a few seconds (depending on your `clearmsg_timeout` config), the message should be read.
|
Connect to the configured Twitch channel and send a message starting with `!tts`. After a few seconds (depending on your `clearmsg_timeout` config), the message should be read.
|
||||||
|
|
||||||
### Additional Commands
|
### Additional Commands
|
||||||
|
|
||||||
Additional commands (broadcaster and mods only) are:
|
Additional commands (broadcaster and mods only) are:
|
||||||
|
|
||||||
* `!ping`: Check if bot is alive (the bot should reply: `Pong!`)
|
* `!ping`: Check if bot is alive (the bot should reply: `Pong!`)
|
||||||
* `!toff`: Turn TTS off (will also empty the current TTS queue)
|
* `!toff`: Turn TTS off (will also empty the current TTS queue)
|
||||||
* `!ton`: Turn TTS back on
|
* `!ton`: Turn TTS back on
|
||||||
* `!dtts <username>`: Disable TTS for the given user
|
* `!dtts <username>`: Disable TTS for the given user
|
||||||
* `!ptts <username>`: Allow TTS for the given user
|
* `!ptts <username>`: Allow TTS for the given user
|
||||||
* `!usermap <username> <spoken name>`: Add an entry to the usermapping in `config.yml`
|
* `!usermap <username> <spoken name>`: Add an entry to the usermapping in `config.yml`
|
||||||
* `!delay <int>`: Adjust the `clearmsg_timeout` in `config.yml`
|
* `!delay <int>`: Adjust the `clearmsg_timeout` in `config.yml`
|
||||||
|
|
||||||
### Additional features
|
### Additional features
|
||||||
|
|
||||||
#### !quickvote
|
#### !quickvote
|
||||||
|
|
||||||
A simple vote system.
|
A simple vote system.
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
1. Broadcaster/Mods: `!quickvote <message>`
|
1. Broadcaster/Mods: `!quickvote <message>`
|
||||||
2. User: `#choice`
|
2. User: `#choice`
|
||||||
3. Broadcaster/Mods: `!quickvote`
|
3. Broadcaster/Mods: `!quickvote`
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
mod: !quickvote Is pizza hawaii any good? #yes/#no
|
mod: !quickvote Is pizza hawaii any good? #yes/#no
|
||||||
chat: #no
|
chat: #no
|
||||||
mod: !quickvote
|
mod: !quickvote
|
||||||
bot: The result is: #no
|
bot: The result is: #no
|
||||||
```
|
```
|
||||||
|
|
||||||
If a message is given by the Mods it will be repeated every 60 seconds, so everyone keeps in mind, that a vote is still active.
|
If a message is given by the Mods it will be repeated every 60 seconds, so everyone keeps in mind, that a vote is still active.
|
||||||
|
|
||||||
#### !pick
|
#### !pick
|
||||||
|
|
||||||
Randomly choose users from chat (who wants to participate).
|
Randomly choose users from chat (who wants to participate).
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
1. Broadcaster/Mods: `!pick <int>`
|
1. Broadcaster/Mods: `!pick <int>`
|
||||||
2. User: #pickme
|
2. User: #pickme
|
||||||
3. Broadcaster/Mods: `!pick`
|
3. Broadcaster/Mods: `!pick`
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
mod: !pick 3
|
mod: !pick 3
|
||||||
user1: #pickme
|
user1: #pickme
|
||||||
user2: #pickme
|
user2: #pickme
|
||||||
user3: #pickme
|
user3: #pickme
|
||||||
user4: #pickme
|
user4: #pickme
|
||||||
user5: #pickme
|
user5: #pickme
|
||||||
mod: !pick
|
mod: !pick
|
||||||
bot: The picked users are: user5, user3, user1
|
bot: The picked users are: user5, user3, user1
|
||||||
```
|
```
|
||||||
|
|
||||||
#### !random
|
#### !random
|
||||||
|
|
||||||
Picks a random line from a file.
|
Picks a random line from a file.
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
* Broadcaster/Mod: `!random <file>`
|
* Broadcaster/Mod: `!random <file>`
|
||||||
|
|
||||||
You can use multiple files, if you call `!random foo` the bot fetch the random line from a file called `random_foo.txt`, `!random bar` will use the file `random_bar.txt` and so on. If no `<file>` is given the command use the file `random.txt`.
|
You can use multiple files, if you call `!random foo` the bot fetch the random line from a file called `random_foo.txt`, `!random bar` will use the file `random_bar.txt` and so on. If no `<file>` is given the command use the file `random.txt`.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
mod: !random
|
mod: !random
|
||||||
bot: This is a random message
|
bot: This is a random message
|
||||||
```
|
```
|
||||||
|
|
||||||
#### !addquote
|
#### !addquote
|
||||||
|
|
||||||
The `!addquote` command adds a new line to `quotes.txt`.
|
The `!addquote` command adds a new line to `quotes.txt`.
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
* Chat: `!addquote <username> <quote>`
|
* Chat: `!addquote <username> <quote>`
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
chat: !addquote gpkvt This is a very funny quote.
|
chat: !addquote gpkvt This is a very funny quote.
|
||||||
bot: Quote #1 was added.
|
bot: Quote #1 was added.
|
||||||
```
|
```
|
||||||
|
|
||||||
#### !smartquote / !sq
|
#### !smartquote / !sq
|
||||||
|
|
||||||
Picks a random/specific line from `quotes.txt`.
|
Picks a random/specific line from `quotes.txt`.
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
* Chat: `!smartquote`
|
* Chat: `!smartquote`
|
||||||
* Chat: `!smartquote <linenumber>`
|
* Chat: `!smartquote <linenumber>`
|
||||||
* Chat: `!smartquote <searchstring>`
|
* Chat: `!smartquote <searchstring>`
|
||||||
* Chat: `!sq`
|
* Chat: `!sq`
|
||||||
* Chat: `!sq <linenumber>`
|
* Chat: `!sq <linenumber>`
|
||||||
* Chat: `!sq <searchstring>`
|
* Chat: `!sq <searchstring>`
|
||||||
|
|
||||||
(`!sq` is an alias for `!smartquote`)
|
(`!sq` is an alias for `!smartquote`)
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
chat: !smartquote
|
chat: !smartquote
|
||||||
bot: This is a random quote
|
bot: This is a random quote
|
||||||
chat: !smartquote 1000
|
chat: !smartquote 1000
|
||||||
bot: This is quote #1000
|
bot: This is quote #1000
|
||||||
chat: !smartquote something stupid
|
chat: !smartquote something stupid
|
||||||
bot: This is a quote containing something stupid (or similiar)
|
bot: This is a quote containing something stupid (or similiar)
|
||||||
```
|
```
|
||||||
|
|
||||||
The format of `quotes.txt` looks as follows:
|
The format of `quotes.txt` looks as follows:
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
#1: "the quote" -username/game (date)
|
#1: "the quote" -username/game (date)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### !wiki
|
#### !wiki
|
||||||
|
|
||||||
Search the Wikipedia.
|
Search the Wikipedia.
|
||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
|
|
||||||
* Chat: `!wiki <searchstring>`
|
* Chat: `!wiki <searchstring>`
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
``` lang=text
|
``` lang=text
|
||||||
chat: !wiki 42 answer
|
chat: !wiki 42 answer
|
||||||
bot: 42 is the "Answer to the Ultimate Question of Life, the Universe, and Everything".
|
bot: 42 is the "Answer to the Ultimate Question of Life, the Universe, and Everything".
|
||||||
```
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows:
|
If you prefer to build your own `tts.exe` instead of using the shipped one, you can do as follows:
|
||||||
|
|
||||||
* Install Python 3
|
* Install Python 3
|
||||||
* Install pyinstaller: `pip install pyinstaller`
|
* Install pyinstaller: `pip install pyinstaller`
|
||||||
* Install the required dependencies: `pip install -r requirements.txt -v`
|
* Install the required dependencies: `pip install -r requirements.txt -v`
|
||||||
* Create the executeable: `pyinstaller --onefile tts.py`
|
* Create the executeable: `pyinstaller --onefile tts.py`
|
||||||
|
|
||||||
## Voices
|
## Voices
|
||||||
|
|
||||||
The voices available depend on your Operating System and/or browser. On some systems only a default voice is available and the `Select voice` dropdown might stay empty or will only show entries after you clicked the `Init` button. Some Android devices will show a huge list of voices, but sounds the same no matter which one you choose.
|
The voices available depend on your Operating System and/or browser. On some systems only a default voice is available and the `Select voice` dropdown might stay empty or will only show entries after you clicked the `Init` button. Some Android devices will show a huge list of voices, but sounds the same no matter which one you choose.
|
||||||
|
|
||||||
On Windows you can install additional voices via `Settings` > `Time & language` > `Speech` > `Add voices` or by simply run `Add speech voices`.
|
On Windows you can install additional voices via `Settings` > `Time & language` > `Speech` > `Add voices` or by simply run `Add speech voices`.
|
||||||
|
|
||||||
Do not use Online-Voices, as this will result in serious delays.
|
Do not use Online-Voices, as this will result in serious delays.
|
||||||
|
|
||||||
## Help
|
## Help
|
||||||
|
|
||||||
Feel free to use the [Issuetracker](https://gitlab.com/gpvkt/twitchtts/-/issues) or send an [E-Mail](mailto:contact-project+gpvkt-twitchtts-38486705-issue-@incoming.gitlab.com) if you experience any problems.
|
Feel free to use the [Issuetracker](https://gitlab.com/gpvkt/twitchtts/-/issues) or send an [E-Mail](mailto:contact-project+gpvkt-twitchtts-38486705-issue-@incoming.gitlab.com) if you experience any problems.
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
[@gpkvt](mailto:contact-project+gpvkt-twitchtts-38486705-issue-@incoming.gitlab.com)
|
[@gpkvt](mailto:contact-project+gpvkt-twitchtts-38486705-issue-@incoming.gitlab.com)
|
||||||
|
|
||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
See [CHANGELOG.md](https://gitlab.com/gpvkt/twitchtts/-/blob/main/CHANGELOG.md)
|
See [CHANGELOG.md](https://gitlab.com/gpvkt/twitchtts/-/blob/main/CHANGELOG.md)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the GPLv3 License - see [LICENSE](https://gitlab.com/gpvkt/twitchtts/-/blob/main/LICENSE) for details.
|
This project is licensed under the GPLv3 License - see [LICENSE](https://gitlab.com/gpvkt/twitchtts/-/blob/main/LICENSE) for details.
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
|
||||||
### Ideas and Testing
|
### Ideas and Testing
|
||||||
|
|
||||||
* [GERBrowny and community](https://www.twitch.tv/gerbrowny/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/303172270/static/light/1.0)
|
* [GERBrowny and community](https://www.twitch.tv/gerbrowny/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/303172270/static/light/1.0)
|
||||||
* [DerZugger and community](https://www.twitch.tv/derzugger/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/302400142/static/light/1.0)
|
* [DerZugger and community](https://www.twitch.tv/derzugger/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/302400142/static/light/1.0)
|
||||||
* [Timmeh74 and community](https://www.twitch.tv/timmeh74/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/300192675/static/light/1.0)
|
* [Timmeh74 and community](https://www.twitch.tv/timmeh74/) ![Emote](https://static-cdn.jtvnw.net/emoticons/v2/300192675/static/light/1.0)
|
||||||
|
|
||||||
### Libraries
|
### Libraries
|
||||||
|
|
||||||
* [Python](https://www.python.org/)
|
* [Python](https://www.python.org/)
|
||||||
* [jQuery](https://jquery.org/)
|
* [jQuery](https://jquery.org/)
|
||||||
* [Bootstrap](https://getbootstrap.com/)
|
* [Bootstrap](https://getbootstrap.com/)
|
||||||
* [PyYAML](https://pyyaml.org/)
|
* [PyYAML](https://pyyaml.org/)
|
||||||
* [requests](https://requests.readthedocs.io/en/latest/)
|
* [requests](https://requests.readthedocs.io/en/latest/)
|
||||||
* [fuzzywuzzy](https://github.com/seatgeek/fuzzywuzzy)
|
* [fuzzywuzzy](https://github.com/seatgeek/fuzzywuzzy)
|
||||||
* [wikipedia](https://github.com/goldsmith/Wikipedia)
|
* [wikipedia](https://github.com/goldsmith/Wikipedia)
|
||||||
* [pyinstaller](https://pyinstaller.org/)
|
* [pyinstaller](https://pyinstaller.org/)
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
|
|
||||||
This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Twitch Interactive, Inc.
|
This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Twitch Interactive, Inc.
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,48 +1,48 @@
|
||||||
irc:
|
irc:
|
||||||
channel: "#changeme" # Your twitch channel
|
channel: "#changeme" # Your twitch channel
|
||||||
username: "changeme" # Your bots username
|
username: "changeme" # Your bots username
|
||||||
oauth_token: # leave this blank to start the token generator
|
oauth_token: # leave this blank to start the token generator
|
||||||
server: "irc.chat.twitch.tv" # Twitch IRC server, default should be fine
|
server: "irc.chat.twitch.tv" # Twitch IRC server, default should be fine
|
||||||
clearmsg_timeout: 10 # Time to wait for a new message to be deleted before being read
|
clearmsg_timeout: 10 # Time to wait for a new message to be deleted before being read
|
||||||
|
|
||||||
http:
|
http:
|
||||||
port: 80 # Internal webserver port
|
port: 80 # Internal webserver port
|
||||||
bind: "localhost" # Internal webserver IP/Hostname, use 0.0.0.0 to listen on all interfaces
|
bind: "localhost" # Internal webserver IP/Hostname, use 0.0.0.0 to listen on all interfaces
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
start_enabled: True # Start the bot with TTS active, if set to False you need to enable TTS with !ton
|
start_enabled: True # Start the bot with TTS active, if set to False you need to enable TTS with !ton
|
||||||
subonly: False # Only Subs can use TTS
|
subonly: False # Only Subs can use TTS
|
||||||
modonly: False # Only Mods can use TTS
|
modonly: False # Only Mods can use TTS
|
||||||
message_length: 200 # Max. TTS message length
|
message_length: 200 # Max. TTS message length
|
||||||
language: de # Language for wikipedia
|
language: de # Language for wikipedia
|
||||||
|
|
||||||
messages: # Things the bot can send as chat message
|
messages: # Things the bot can send as chat message
|
||||||
toff: "TTS is now inactive."
|
toff: "TTS is now inactive."
|
||||||
ton: "TTS is now active."
|
ton: "TTS is now active."
|
||||||
too_long: "Sorry, your TTS message is too long."
|
too_long: "Sorry, your TTS message is too long."
|
||||||
disabled: "Sorry, TTS is disabled right now."
|
disabled: "Sorry, TTS is disabled right now."
|
||||||
denied: "Sorry, you are not allowed to use TTS."
|
denied: "Sorry, you are not allowed to use TTS."
|
||||||
whitelist: "Sorry, you are not allowed to use TTS."
|
whitelist: "Sorry, you are not allowed to use TTS."
|
||||||
subonly: "Sorry, TTS is a sub-only feature."
|
subonly: "Sorry, TTS is a sub-only feature."
|
||||||
modonly: "Sorry, TTS is a mod-only feature."
|
modonly: "Sorry, TTS is a mod-only feature."
|
||||||
ready: "TTS bot alpha ready!"
|
ready: "TTS bot alpha ready!"
|
||||||
says: "says"
|
says: "says"
|
||||||
votestart: "Quickvote started. Send #yourchoice to participate."
|
votestart: "Quickvote started. Send #yourchoice to participate."
|
||||||
voteend: "Quickvote ended. The results are:"
|
voteend: "Quickvote ended. The results are:"
|
||||||
votenobody: "Nobody casted a vote. :("
|
votenobody: "Nobody casted a vote. :("
|
||||||
voteresult: "Voting has ended. The result is:"
|
voteresult: "Voting has ended. The result is:"
|
||||||
votes: "Votes"
|
votes: "Votes"
|
||||||
pickstart: "Pick started. Send #pickme to participate."
|
pickstart: "Pick started. Send #pickme to participate."
|
||||||
pickresult: "Pick ended. The results are:"
|
pickresult: "Pick ended. The results are:"
|
||||||
picknone: "Nobody was picked. :("
|
picknone: "Nobody was picked. :("
|
||||||
quotenotfound: "Sorry, no quote found."
|
quotenotfound: "Sorry, no quote found."
|
||||||
quoteaddedprefix: "Quote:"
|
quoteaddedprefix: "Quote:"
|
||||||
quoteaddedsuffix: "added."
|
quoteaddedsuffix: "added."
|
||||||
wiki_too_many: "Sorry, there are too many possible results. Try a more narrow search."
|
wiki_too_many: "Sorry, there are too many possible results. Try a more narrow search."
|
||||||
wiki_no_result: "Sorry, there was an error fetching the wikipedia answer."
|
wiki_no_result: "Sorry, there was an error fetching the wikipedia answer."
|
||||||
|
|
||||||
log:
|
log:
|
||||||
level: "INFO" # Loglevel, valid values are: DEBUG, INFO, WARNING, ERROR, CRITICAL (do not use DEBUG in a production environment)
|
level: "INFO" # Loglevel, valid values are: DEBUG, INFO, WARNING, ERROR, CRITICAL (do not use DEBUG in a production environment)
|
||||||
|
|
||||||
usermapping:
|
usermapping:
|
||||||
gpkvt: "gpk" # rename users when being read, to make their names shorter or sound better.
|
gpkvt: "gpk" # rename users when being read, to make their names shorter or sound better.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fuzzywuzzy==0.18.0
|
fuzzywuzzy==0.18.0
|
||||||
PyInstaller==5.3
|
PyInstaller==5.3
|
||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
requests==2.28.1
|
requests==2.28.1
|
||||||
wikipedia==1.4.0
|
wikipedia==1.4.0
|
||||||
|
|
98
tts.html
98
tts.html
|
@ -1,49 +1,49 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<link href="./bootstrap.min.css" rel="stylesheet" />
|
<link href="./bootstrap.min.css" rel="stylesheet" />
|
||||||
<title>TTS</title>
|
<title>TTS</title>
|
||||||
<script src="./jquery.js"></script>
|
<script src="./jquery.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="container mt-2">
|
<body class="container mt-2">
|
||||||
<p class="lead mt-2">Select Voice</p>
|
<p class="lead mt-2">Select Voice</p>
|
||||||
<select id="voices" class="form-select bg-transparent"></select>
|
<select id="voices" class="form-select bg-transparent"></select>
|
||||||
<div class="d-flex mt-2">
|
<div class="d-flex mt-2">
|
||||||
<div>
|
<div>
|
||||||
<p class="lead">Volume</p>
|
<p class="lead">Volume</p>
|
||||||
<input type="range" min="0" max="1" value="1" step="0.1" id="volume" />
|
<input type="range" min="0" max="1" value="1" step="0.1" id="volume" />
|
||||||
<span id="volume-label" class="ms-2">1</span>
|
<span id="volume-label" class="ms-2">1</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-4">
|
<div class="mx-4">
|
||||||
<p class="lead">Rate</p>
|
<p class="lead">Rate</p>
|
||||||
<input type="range" min="0.1" max="10" value="1" id="rate" step="0.1" />
|
<input type="range" min="0.1" max="10" value="1" id="rate" step="0.1" />
|
||||||
<span id="rate-label" class="ms-2">1</span>
|
<span id="rate-label" class="ms-2">1</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="lead">Pitch</p>
|
<p class="lead">Pitch</p>
|
||||||
<input type="range" min="0" max="2" value="1" step="0.1" id="pitch" />
|
<input type="range" min="0" max="2" value="1" step="0.1" id="pitch" />
|
||||||
<span id="pitch-label" class="ms-2">1</span>
|
<span id="pitch-label" class="ms-2">1</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="start" class="btn btn-success mt-4 me-2">Init</button>
|
<button id="start" class="btn btn-success mt-4 me-2">Init</button>
|
||||||
<button id="pause" class="btn btn-warning mt-4 me-2">Pause</button>
|
<button id="pause" class="btn btn-warning mt-4 me-2">Pause</button>
|
||||||
<button id="resume" class="btn btn-info mt-4 me-2">Resume</button>
|
<button id="resume" class="btn btn-info mt-4 me-2">Resume</button>
|
||||||
<button id="cancel" class="btn btn-danger mt-4 me-2">Cancel</button>
|
<button id="cancel" class="btn btn-danger mt-4 me-2">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
<script src="./tts.js"></script>
|
<script src="./tts.js"></script>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready (function(){
|
$(document).ready (function(){
|
||||||
if (window.matchMedia) {
|
if (window.matchMedia) {
|
||||||
if(window.matchMedia('(prefers-color-scheme: dark)').matches){
|
if(window.matchMedia('(prefers-color-scheme: dark)').matches){
|
||||||
$('body').addClass('bg-dark');
|
$('body').addClass('bg-dark');
|
||||||
$('p').addClass('text-light');
|
$('p').addClass('text-light');
|
||||||
$('select').addClass('text-light');
|
$('select').addClass('text-light');
|
||||||
$('option').addClass('bg-dark');
|
$('option').addClass('bg-dark');
|
||||||
$('span').addClass('text-light');
|
$('span').addClass('text-light');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue