Test Drive: Deepgram TTS
Published on .
WordPress database error: [<div style="clear:both"> </div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/>
<ol>
<li>Raw query:
SELECT * FROM wp_options WHERE </li>
<li>Rewritten:
SELECT * FROM wp_options WHERE </li>
<li>With Placeholders:
SELECT * FROM wp_options WHERE </li>
<li>Prepare:
SELECT * FROM wp_options WHERE </li>
</ol>
</div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message()
#1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...')
#2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update()
#3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...')
#4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...')
#5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...')
#6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...')
#7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1552): add_option('...', 1758091536, '', '...')
#8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000)
#9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block))
#10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render()
#11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array)
#12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...')
#13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array)
#14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...')
#15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content()
#16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...')
#17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...')
#18 /home/nattaylor/public_html/wordpress/index.php(17): require('...')
</pre>]
SELECT * FROM wp_options WHERE
WordPress database error: [<div style="clear:both"> </div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/>
<ol>
<li>Raw query:
SELECT * FROM wp_options WHERE </li>
<li>Rewritten:
SELECT * FROM wp_options WHERE </li>
<li>With Placeholders:
SELECT * FROM wp_options WHERE </li>
<li>Prepare:
SELECT * FROM wp_options WHERE </li>
</ol>
</div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message()
#1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...')
#2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update()
#3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...')
#4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...')
#5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...')
#6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...')
#7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1554): add_option('...', Array, '', '...')
#8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000)
#9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block))
#10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render()
#11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array)
#12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...')
#13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array)
#14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...')
#15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content()
#16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...')
#17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...')
#18 /home/nattaylor/public_html/wordpress/index.php(17): require('...')
</pre>]
SELECT * FROM wp_options WHERE
WordPress database error: [<div style="clear:both"> </div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/>
<ol>
<li>Raw query:
SELECT * FROM wp_options WHERE </li>
<li>Rewritten:
SELECT * FROM wp_options WHERE </li>
<li>With Placeholders:
SELECT * FROM wp_options WHERE </li>
<li>Prepare:
SELECT * FROM wp_options WHERE </li>
</ol>
</div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message()
#1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...')
#2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update()
#3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...')
#4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...')
#5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...')
#6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...')
#7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1552): add_option('...', 1758091536, '', '...')
#8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000)
#9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block))
#10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render()
#11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array)
#12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...')
#13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array)
#14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...')
#15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content()
#16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...')
#17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...')
#18 /home/nattaylor/public_html/wordpress/index.php(17): require('...')
</pre>]
SELECT * FROM wp_options WHERE
WordPress database error: [<div style="clear:both"> </div><div class="queries" style="clear:both; margin_bottom:2px; border: red dotted thin;">Queries made or created this session were<br/>
<ol>
<li>Raw query:
SELECT * FROM wp_options WHERE </li>
<li>Rewritten:
SELECT * FROM wp_options WHERE </li>
<li>With Placeholders:
SELECT * FROM wp_options WHERE </li>
<li>Prepare:
SELECT * FROM wp_options WHERE </li>
</ol>
</div><div style="clear:both; margin_bottom:2px; border: red dotted thin;" class="error_message" style="border-bottom:dotted blue thin;">Error occurred at line 1644 in Function prepare_query. <br/> Error message was: Problem preparing the PDO SQL Statement. Error was: SQLSTATE[HY000]: General error: 1 incomplete input </div><pre>#0 /home/nattaylor/public_html/wordpress/wp-content/db.php(2746): WP_SQLite_DB\PDOEngine->get_error_message()
#1 /home/nattaylor/public_html/wordpress/wp-content/db.php(3484): WP_SQLite_DB\wpsqlitedb->query('...')
#2 /home/nattaylor/public_html/wordpress/wp-content/db.php(2952): WP_SQLite_DB\PDOSQLiteDriver->execute_duplicate_key_update()
#3 /home/nattaylor/public_html/wordpress/wp-content/db.php(1893): WP_SQLite_DB\PDOSQLiteDriver->rewrite_query('...', '...')
#4 /home/nattaylor/public_html/wordpress/wp-content/db.php(1357): WP_SQLite_DB\PDOEngine->execute_insert_query_new('...')
#5 /home/nattaylor/public_html/wordpress/wp-content/db.php(2739): WP_SQLite_DB\PDOEngine->query('...')
#6 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1143): WP_SQLite_DB\wpsqlitedb->query('...')
#7 /home/nattaylor/public_html/wordpress/wp-includes/option.php(1554): add_option('...', Array, '', '...')
#8 /home/nattaylor/public_html/wordpress/wp-content/plugins/syntax-highlighting-code-block/inc/functions.php(671): set_transient('...', Array, 2592000)
#9 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-block.php(586): Syntax_Highlighting_Code_Block\render_block(Array, '...', Object(WP_Block))
#10 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2359): WP_Block->render()
#11 /home/nattaylor/public_html/wordpress/wp-includes/blocks.php(2431): render_block(Array)
#12 /home/nattaylor/public_html/wordpress/wp-includes/class-wp-hook.php(324): do_blocks('...')
#13 /home/nattaylor/public_html/wordpress/wp-includes/plugin.php(205): WP_Hook->apply_filters('...', Array)
#14 /home/nattaylor/public_html/wordpress/wp-includes/post-template.php(256): apply_filters('...', '...')
#15 /home/nattaylor/public_html/wordpress/wp-content/themes/ntdc/index.php(70): the_content()
#16 /home/nattaylor/public_html/wordpress/wp-includes/template-loader.php(106): include('...')
#17 /home/nattaylor/public_html/wordpress/wp-blog-header.php(19): require_once('...')
#18 /home/nattaylor/public_html/wordpress/index.php(17): require('...')
</pre>]
SELECT * FROM wp_options WHERE
Today I test drove Deepgram’s TTS offering since they give free credits. I’m making a podcast out of the East Boston Oral History that I mentioned yesterday. The process is:
- Get an API key
- Invoke
The code is very simple and returns decent audio.
from deepgram import DeepgramClient, SpeakOptions
deepgram = DeepgramClient()
def speak(text, filename):
response = deepgram.speak.v("1").save(filename, {"text": text}, SpeakOptions(model="aura-arcas-en"))
I suppose making the podcast is much more interesting. Here is the code for that, as well as a sample.
So the steps are:
- Transcribe
- Generate intro and outro text based on the transcription
- Generate speech
- Dub it all together
- Generate the feed
If I were to do this again, I would have just used the OpenAI TTS.
import glob
import pydub
from pydantic import BaseModel
from openai import OpenAI
from pathlib import Path
from deepgram import DeepgramClient, SpeakOptions
client = OpenAI()
class PodcastText(BaseModel):
intro: str
outro: str
def generate_text(text):
return client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are the podcast host of \"East Boston Oral History Podcast\" who writes intros and outros based on the transcript."},
{"role": "user", "content": text}
],
response_format=PodcastText,
).choices[0].message.parsed
deepgram = DeepgramClient()
def speak(text, filename):
response = deepgram.speak.v("1").save(filename, {"text": text}, SpeakOptions(model="aura-arcas-en"))
return response.filename
episodes = []
for f in glob.glob('/Users/ntaylor/Downloads/East Boston Oral History/*.mp3'):
p = Path(f)
result = mlx_whisper.transcribe(f, path_or_hf_repo="mlx-community/whisper-large-v3-turbo")
text = generate_text(result['text'])
intro = speak(text.intro, 'intro.mp3')
outro = speak(text.outro, 'outro.mp3')
audio = (
pydub.AudioSegment.from_mp3("Greenway Groove.mp3")[:10000].fade_out(3000)
.append(pydub.AudioSegment.from_mp3(intro))
.append(pydub.AudioSegment.from_mp3(f)[:10000])
.append(pydub.AudioSegment.from_mp3(outro))
)
audio.export(f'Episode {p.parts[-1]}', format="mp3")
display(Audio(f'Episode {p.parts[-1]}'))
episodes.append({
'name': p.stem,
'duration': int(audio.duration_seconds),
'file': p.name,
})
# see https://assets.ctfassets.net/jtdj514wr91r/3khl5YaRusSuQ4a18amk38/8f35aecf398979cdfa6839ae29e79a46/Podcast_Delivery_Specification_v1.9.pdf
from feedgen.feed import FeedGenerator
from datetime import datetime, timezone
dt = datetime.now()
dt = dt.replace(tzinfo=timezone.utc)
fg = FeedGenerator()
fg.load_extension('podcast')
fg.title('East Boston Oral History Podcast')
fg.link( href='http://example.com', rel='alternate' )
fg.description('foo')
fg.podcast.itunes_author('Nat Taylor')
fg.podcast.itunes_category('History')
fg.podcast.itunes_type('episodic')
fg.podcast.itunes_image('http://ex.com/logo.jpg')
fg.language('en')
for i,e in enumerate(episodes):
fe = fg.add_entry()
fe.guid('123')
fe.title(e['name'])
fe.description('foo')
fe.pubDate(dt.isoformat())
fe.podcast.itunes_order(i)
fe.podcast.itunes_duration(e['duration'])
fe.enclosure(url=f"http://example.com/{e['file']}", length=e['duration'], type='audio/mpeg')
# fg.rss_file('podcast.xml')
print(fg.rss_str(pretty=True).decode('utf8'))