Speak
view release on metacpan or search on metacpan
lib/Speak.pm view on Meta::CPAN
my $content = $response->content;
if (length ($content) == 0) {
carp "Fetch successful but content is empty";
return;
}
# Check if we got HTML instead of MP3 (e.g. Captcha/Error)
if ($content =~ /^\s*<(!DOCTYPE|html)/i) {
carp
"Received HTML response instead of MP3 (likely CAPTCHA/Blocked) from URL: $url";
return;
}
return $content;
} else {
carp "Failed to fetch TTS: " . $response->status_line;
return;
}
} ## end sub _fetch_mp3 ($$$)
sub _convert_mp3_to_wav ($mp3, $wav) {
# Try ffmpeg
if (system ("which ffmpeg >/dev/null 2>&1") == 0) {
return system ("ffmpeg -y -v error -i \"$mp3\" \"$wav\"") == 0;
}
# Try mpg123
if (system ("which mpg123 >/dev/null 2>&1") == 0) {
return system ("mpg123 -q -w \"$wav\" \"$mp3\"") == 0;
}
# Try lame
if (system ("which lame >/dev/null 2>&1") == 0) {
return system ("lame --decode --quiet \"$mp3\" \"$wav\"") == 0;
}
# Fallback to sox (might fail if no mp3 handler)
return system ("sox \"$mp3\" \"$wav\"") == 0;
} ## end sub _convert_mp3_to_wav ($$)
## no critic (Subroutines::ProhibitExcessComplexity)
sub speak ($msg, $log = undef, $lang = undef) {
=pod
=head2 speak($msg, $log, $lang)
Convert $msg to speech.
Parameters:
=for html <blockquote>
=over
=item $msg:
Message to speak. If $msg is defined and scalar then that is the message
to speak. If it is a file handle then the text will be read from that file.
Otherwise the text in the clipboard will be used.
=item $log
If provided, errors and messages will be logged to the logfile, otherwise to speak.log
=item $lang
Language code (e.g. 'en', 'en-gb', 'en-au'). Defaults to $ENV{SPEAK_LANG} or 'en'.
=back
=for html </blockquote>
Returns:
=for html <blockquote>
=over
=item Nothing
=back
=for html </blockquote>
=cut
$log = Speak::Logger->new (
path => '/var/log',
name => 'speak',
timestamped => 'yes',
append => 1,
) unless $log;
$msg = Clipboard->paste unless $msg;
$msg = do {local $/; <$msg>} if ref $msg eq 'GLOB';
# Sanitize escape sequences
# 1. Remove bells (\a)
$msg =~ s/(\\a|\a)//g;
# 2. Convert other escapes to space
# Literals: \n, \t, \r, \f, \b
$msg =~ s/\\[ntrfb]/ /g;
# 3. Convert actual control characters to space
$msg =~ s/[\n\t\r\f\b]/ /g;
# 4. Collapse multiple spaces
$msg =~ s/\s+/ /g;
$msg =~ s/^\s+|\s+$//g;
my @mute_paths =
($ENV{SPEAK_MUTE}, $ENV{HOME} . "/.speak/shh", "/etc/speak/shh");
foreach my $path (@mute_paths) {
if ($path && -f $path) {
$msg .= ' [silent shh]';
( run in 4.256 seconds using v1.01-cache-2.11-cpan-bbc515a03b3 )