https://github.com/generalyadoc/chataistreamer
Get ChatGPT voiced answer of YouTube chat stream
https://github.com/generalyadoc/chataistreamer
chatgpt gtts livestreaming pydub youtube
Last synced: about 1 month ago
JSON representation
Get ChatGPT voiced answer of YouTube chat stream
- Host: GitHub
- URL: https://github.com/generalyadoc/chataistreamer
- Owner: GeneralYadoc
- License: mit
- Created: 2023-05-28T12:08:35.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-06-19T14:23:48.000Z (over 2 years ago)
- Last Synced: 2025-08-30T04:39:53.518Z (about 1 month ago)
- Topics: chatgpt, gtts, livestreaming, pydub, youtube
- Language: Python
- Homepage: https://www.youtube.com/embed/sesl9VZHDA8
- Size: 44.9 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ChatAIStreamer
Extention of [ChatAIStream](https://github.com/GeneralYadoc/ChatAIStream) for voice generation.## The user of this library can
- pick up massegase from YouTube Chat and generate answer by ChatGPT.
- easily give role to ChatGPT.
- add callback of voice generation and get the return through answer_with_voice_cb.## How to install
### Install from PyPI
- Install package to your environment.
```install
$ pip install chatai-streamer
```### Install from GitHub repository
- Clone this repository.
```clone
$ clone https://github.com/GeneralYadoc/ChatAIStreamer.git
```
- Change directory to the root of the repository.
```cd
$ cd ChatAIStreamer
```
- Install package to your environment.
```install
$ pip install .
```
## How to use
- [OpenAI API Key](https://www.howtogeek.com/885918/how-to-get-an-openai-api-key/) is necessary.- You can use ChatAIStreamer class by implementing 'Add Implement' blocks of following codes.
``` example
import sys
import ChatAIStreamer as casr # Import thisclass myVoiceGenerator(casr.voiceGenerator):
def generate(self, text):
optimized_text = None
voice = None#### Add Implementation here.
# Optimize text for your TTS and assign to optimized_text variable.
# Generate voice from optimized_text and assign to voice variable.
# There is no restriction of the type of the voice.
####return optimized_text, voice
# callback for getting answer of ChatGPT
# The voice generated by voiceGenerator is given as an argument.
def answer_with_voice_cb(user_message, completion, voice):
#### Add Implementation here.
# Implement for visualizing message (given as user_message).
# Implement for visualizing ChatGPT answer (given as completion).
# Implement for playing voice generated myVoiceGenerator.
####running = False
# YouTube Video ID and ChatGPT API Key is given from command line in this example.
if len(sys.argv) <= 2:
exit(0)# Set params of getting messages from stream source.
stream_params=casr.streamParams(video_id=sys.argv[1])# Set params of Chat AI.
ai_params=casr.aiParams(
api_key = sys.argv[2],
system_role = "You are a cheerful assistant who speek English and can get conversation exciting with user."
)# Set params of streamer
streamer_params=casr.streamerParams(
voice_generator=myVoiceGenerator(),
answer_with_voice_cb=answer_with_voice_cb
)# Create ChatAIStreamer instance.
ai_streamer =casr.ChatAIStreamer(
casr.params(
stream_params=stream_params,
ai_params=ai_params,
streamer_params=streamer_params
)
)running = True
# Wake up internal thread to get chat messages from stream and play voices of reading ChatGPT answers aloud.
ai_streamer.start()# Wait any key inputted from keyboad.
input()# Turn off runnging flag in order to finish playing voices of the sample.
running=False# Finish generating voices.
# Internal thread will stop soon.
ai_streamer.disconnect()# terminating internal thread.
ai_streamer.join()del ai_streamer
```
## GttsAIStreamer - sample wrapper of ChatAIStreamer
- Sample class named [GttsAIStreamer](src/GttsAIStreamer.py) is provided with which you can play ChatGPT answers by gTTS voice.
- You can get gTTS voice and play it by the class.
- Sample codes using GttsAIStreamer exist [here](samples/sample.py).
``` sample.py
# To execute this sample, please install ffmpeg.
import sys
import time
import math
import datetime
import GttsAIStreamer as gasr# print sentence by a character incrementally.
def print_incremental(st, interval_sec):
for i in range(len(st)):
if not running:
break
print(f"{st[i]}", end='')
sys.stdout.flush()
interruptible_sleep(interval_sec)# Customized sleep for making available of running flag interruption.
def interruptible_sleep(time_sec):
counter = math.floor(time_sec / 0.10)
frac = time_sec - (counter * 0.10)
for i in range(counter):
if not running:
break
time.sleep(0.10)
if not running:
return
time.sleep(frac)# callback for getting answer of ChatGPT
# The voice generated by GttsGenerator is given.
def answer_with_voice_cb(user_message, completion, voice):
print(f"\n[{user_message.extern.author.name} {user_message.extern.datetime}] {user_message.message}\n")
time_str = datetime.datetime.now().strftime ('%H:%M:%S')
message = completion.choices[0]["message"]["content"]# Play the voice by VoicePlayer of GttsAIStreamer
# If you use Python launcher named py, please create proper player as follows.
# player = gasr.VoicePlayer(voice, python_command="py")
player = gasr.VoicePlayer(voice)
player.start()interruptible_sleep(3)
print(f"[ChatGPT {time_str}] ", end='')
print_incremental(message, 0.05)
print("\n")# Wait finishing Playng the voice.
player.join()running = False
# YouTube Video ID and ChatGPT API Key is given from command line in this example.
if len(sys.argv) <= 2:
exit(0)# Set params of getting messages from stream source.
stream_params=gasr.streamParams(video_id=sys.argv[1])# Set params of Chat AI.
ai_params=gasr.aiParams(
api_key = sys.argv[2],
system_role = "You are a cheerful assistant who speek English and can get conversation exciting with user.",
)# Create GttsVoiceGenerator
# You can choose other language by its 'lang=' argument like 'ja'.
# If you want to change language, Please change the assignment for system role of ai params also.
# The instance isn't necessary for English generator.
streamer_params=gasr.streamerParams(
voice_generator=gasr.GttsGenerator(lang='en'),
answer_with_voice_cb=answer_with_voice_cb
)# Create GttsAIStreamer instance.
# 'voice_generator=' is omittable for English generator.
ai_streamer =gasr.GttsAIStreamer(
gasr.params(
stream_params=stream_params,
ai_params=ai_params,
streamer_params=streamer_params
)
)running = True
# Wake up internal thread to get chat messages from stream and play gTTS voices of reading ChatGPT answers aloud.
ai_streamer.start()# Wait any key inputted from keyboad.
input()# Turn off runnging flag in order to finish playing gTTS voices of the sample.
running=False# Finish generating gTTS voices.
# Internal thread will stop soon.
ai_streamer.disconnect()# terminating internal thread.
ai_streamer.join()del ai_streamer
```### Usage of the sample
- Install ffmpeg
For Linux: Execute following command.
```ffmpeg installation for Linux
$ sudo apt-get install ffmpeg
```
For Windows: Access [here](https://github.com/BtbN/FFmpeg-Builds/releases), download '*-win64-gpl.zip', extract the zip and move three exe files (ffmpeg.exe, ffprobe.exe, ffplay.exe) to the folder where you'll execute the sample or added path.
For Mac: Access [here](https://brew.sh/), copy installation command to your terminal and push Enter key, and execute following command.
```
brew install ffmpeg
```- Execution command
```usage
$ python3 ./sample.py VIDEO-ID OpenAI-API-KEY
```
- Output of the sample
The outputs of the voices and the right window are provided by this sample.
Left outputs are also available by ChatAIStreamer.
[](https://www.youtube.com/embed/k_7Ona9JuBo)## Arguments of Constructor
- ChatAIStreamer object can be configured with following params given to constructor.### streamParams
| name | description | default |
|------|------------|---------|
| video_id | String following after 'v=' in url of target YouTube live | - |
| get_item_cb | Chat items are thrown to this callback | None |
| pre_filter_cb | Filter set before internal queue | None |
| post_filter_cb | Filter set between internal queue and get_item_cb | None |
| max_queue_size | Max slots of internal queue (0 is no limit) | 1000 |
| interval_sec | Polling interval of picking up items from YouTube | 0.01 \[sec\] |### aiParams
| name | description | default |
|------|------------|---------|
| api_key | API Key string of OpenAI | - |
| system_role | ChatGPT role in convesation | "You are a helpful assistant." |
| ask_cb | user message given to ChatGPT is thrown to this callback | None |
| max_messages_in_context | Max messages in context given to ChatGPT | 20 |
| answer_cb | ChatGPT answer is thrown to this callback | None |
| max_queue_size | Max slots of internal queue (0 is no limit) | 10 |
| model | Model of AI to be used. | None |
| max_tokens_per_request | Max number of tokens which can be contained in a request | 256 |
| interval_sec | Interval of ChatGPT API call | 20.0 \[sec\] |### streamerParams
| name | description | default |
|------|------------|---------|
| voice_generator | the instance of inherited class of voiceGenerater made by you | None |
| answer_with_voice_cb | ChatGPT answer is thrown to this callback with voice data created by your get method of voiceGenerator | None |
| max_queue_size | max size of internal queue which stocks GPT answer which will be given to voice Generator | 1 |
### Notice
- Please refer [pytchat README](https://github.com/taizan-hokuto/pytchat) to know the type of YouTube Chat item used by get_item_cb, pre_filter_cb and post filter_cb.
- Stamps in a message and messages consisted by stamps only are removed defaultly even if user doesn't set pre_filter_cb.
- Default value of interval_sec is 20.0, since free user of OpenAI API can get only 3 completions per minitue.
- The system role given by user remains ever as the oldest sentence of current context even if the number of messages is reached to the maximum, so ChatGPT doesn't forgot the role while current cunversation.## Methods
### start()
- Start YouTube Chat polling, ChatGPT conversation and voice generation, then start calling user callbacks asyncronously.
- No arguments required, nothing returns.### join()
- Wait terminating internal threads kicked by start().
- No arguments required, nothing returns.### connect()
- Start YouTube Chat polling, ChatGPT conversation and voice generation, then start calling user callbacks syncronously.
- Lines following the call of the method never executen before terminate of internal threads.
- No arguments required, nothing returns.### disconnect()
- Request to terminate YouTube Chat polling, ChatGPT conversation, voice generation and calling user callbacks.
- Internal process will be terminated soon after.
- No arguments required, nothing returns.And other [threading.Thread](https://docs.python.org/3/library/threading.html) public pethods are available.
## Classes
### voiceGenerator
- voiceGenerator class has hollowing method.
| name | description | default |
|------|------------|---------|
| generate | virtual method to generate voice. String of text is given. Modified text and generated voice shoud be returended by this method. The type of modified text shoud be string. No restriction exists for voice type. | - |## Callbacks
### get_item_cb
- Callback for getting YouTube chat items.
- You can implement several processes in it.
- YouTube chat item is thrown as an argument.
- It's not be assumed that any values are returned.
### pre_filter_cb
- pre putting queue filter.
- YouTube chat item is thrown as an argument.
- You can edit YouTube chat items before putting internal queue.
- If you want to get Complete items from YouTube, please implement this callback, since emoticons in a message and messages consisted by emoticons only are already removed from the items gotten in get_item_cb.
- It's required that edited chat item is returned.
- You can avoid putting internal queue by returning None.
### post_filter_cb
- post getting queue filter
- You can edit YouTube chat items after popping internal queue.
- It's required that edited chat item is returned.
- You can avoid sending item to get_item_cb by returning None.
### ask_cb
- Callback for getting questions that actually thrown to ChatGPT.
- If you register external info to user message when you put it, you can obtain the external info here.
- It's not be assumed that any values are returned.
### answer_cb
- Callback for getting question and answer of ChatGPT.
- The type of completion is mentioned [here](https://platform.openai.com/docs/guides/chat).
- It's not be assumed that any values are returned.
### answer_with_voice_cb
- Callback for getting question and answer of ChatGPT with voice data created by your generate method of voiceGenerator.
- The type of completion is mentioned [here](https://platform.openai.com/docs/guides/chat).
- if you modify the answer of ChatGPT on generate method of voiceGenerator, the modification will be reflect to completion argument of this callback.
- ask_cb and this callback are not always sequencial, since voice generation is performed on other thread in order to minimize latency.
- It's not be assumed that any values are returned.## Links
uses following libraries internally.- [chatai-stream](https://github.com/GeneralYadoc/ChatAIStream)
Message broker between YouTube chat stream and ChatGPT.