Jump to content

UDF _text2mp3()


lod3n
 Share

Recommended Posts

This is an enhanced version of my answer to a support question about how to have SAPI write to a file. You must have lame.exe in the same directory as the script for this to work without changing $lameexe, located here: http://www.rarewares.org/mp3.html

The 3rd parameter is the name of the voice you want to use. You can just say "Mike" if you've only got one Mike installed. To get a list, just pass an invalid voice name and it will pop up a list of valid names. Or leave it blank or use "" to just use the default voice.

The 4th parameter is the LAME encoder command line options. You can specify bitrate, mono/stereo etc. Take a look at the LAME documentation for information on this.

This UDF could be used with IE.au3 to convert a news web page to an audio file, or to convert an ebook to a audio book. I have tested this with very large files, and I suggest that if you want to do so too, that you break up the job into smaller peices. For an Ebook for instance, try and break the file up into chapters, and convert the chapters as individual files. I can't tell you how to do this, because I don't know what format your text is in. Also, the voice you are using might have an upper limit for text input or filesize output.

This UDF creates a temporary 16 bit mono 22kHz PCM WAV file (not CD quality, but it sounds fine), so make sure you have enough disk space in your @TempDir before calling it with a huge block of text.

Have fun, and let the forum know if you do anything cool with it!

;example usage below
$text = "Text to MP3 using AutoIt, SAPI, and LAME."
$mp3file = @scriptdir&"\testfile.mp3"
_text2mp3($text,$mp3file,"Microsoft Mike")
SoundPlay ($mp3file,true)

;
func _text2mp3($text,$mp3file,$myvoice="",$lameoptions="") ; see lame.exe options with "lame -?" in a cmd prompt
    $lameexe = @scriptdir&"\lame.exe" ; you'll need to change this to wherever you have the lame.exe file
    
    $tempwav = @tempdir & "\" & random(1000,9999) & ".wav"

    $SSFMCreateForWrite = 3
    $objVOICE = ObjCreate("SAPI.SpVoice")
    $objFSTRM = ObjCreate("SAPI.SpFileStream")
    $objVTOKN = ObjCreate("SAPI.ISpeechObjectToken")

    if $myvoice <> "" Then
        dim $aVoices[1]
        $vIndex = -1
        $sVoices = ""
        For $objVTOKN In $objVOICE.GetVoices()
            $vIndex += 1
            redim $aVoices[$vIndex+1]
            $aVoices[$vIndex] = $objVTOKN.GetDescription()
            $sVoices &= @crlf & "  " & $objVTOKN.GetDescription()
        Next
        $noVoice = True
        for $i = 0 to Ubound($aVoices)-1
            if stringinstr($aVoices[$i],$myvoice) Then
                $objVOICE.Voice = $objVOICE.GetVoices().Item($i)
                $noVoice = False
                ExitLoop
            EndIf
        Next
    
        if $novoice Then
            $errmsg = "The following voices are installed on your system:"&@crlf &$sVoices
            $errmsg &= @crlf & @crlf & "Continuing with the default SAPI voice."
            msgbox(16,'Cannot find voice "'&$myvoice&'"',$errmsg)
        EndIf
    EndIf

    consolewrite("Speaking to WAV file..."&@crlf)
    $objFSTRM.Open($tempwav , $SSFMCreateForWrite, False)
    $objVOICE.AudioOutputStream = $objFSTRM
    $objVOICE.Speak($text)
    $objFSTRM.Close
    $objFSTRM = 0
    $objVOICE = 0

    consolewrite("Encoding WAV file to MP3..."&@crlf)
    $return = runwait('"'&$lameexe&'" '&$lameoptions&' "'&$tempwav&'" "'&$mp3file&'"',@scriptdir, @SW_HIDE)
    consolewrite("Lame.exe exit code: "&$return & @crlf)
    filedelete($tempwav)    
    return $return
EndFunc
Edited by lod3n

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

My results with a large file:

I converted an ebook that had about 47 thousand words (average I think). It took 9 minutes to create the 745 MB WAV file. The MP3 encoding process took 11 minutes and created a 66 MB MP3 file that was 4 hours and 48 minutes long.

Your mileage may vary. :lmao:

Edited by lod3n

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

lod3n

The UDF works great. But being amateur I need some help please.

I am trying to extract the parts I need from the UDF but fail.

1. I want to remove voice check and let it either use the default voice

or give a message that files are missing.

2. I want to use only the convert to MP3 part, supplying the wav file path in a string.

Can you please write those two scripts for me ?

Many thanks

Tuk

Edited by Tukata
Link to comment
Share on other sites

Sorry, I should have made it more obvious, but if you don't supply the voice parameter, like this

_text2mp3($text,$mp3file)oÝ÷ Ú+pYcºË`¡¨^"¶ay×jém¾x¢»azÇ¢wij»h*.®«²Ø¨ØZ·ly«2jëh×6func _wav2mp3($wavfile,$mp3file,$lameoptions = "") ; see lame.exe options with "lame -?" in a cmd prompt
    $lameexe = @scriptdir&"\lame.exe" ; you'll need to change this to wherever you have the lame.exe file

    consolewrite("Encoding WAV file to MP3..."&@crlf)
    $return = runwait('"'&$lameexe&'" '&$lameoptions&' "'&$wavfile&'" "'&$mp3file&'"',@scriptdir, @SW_HIDE)
    consolewrite("Lame.exe exit code: "&$return & @crlf) 
    return $return
EndFunc

Edited by lod3n

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

I am doing something wrong but don't know what :lmao:

This is my whole script, I added only the first two lines to your script:

$wavfile = @scriptdir&"\input.wav"
$mp3file = @scriptdir&"\output.mp3"

func _wav2mp3($wavfile,$mp3file)
    $lameexe = @scriptdir&"\lame.exe"

    consolewrite("Encoding WAV file to MP3..."&@crlf)
    $return = runwait('"'&$lameexe&'" '&$lameoptions&' "'&$wavfile&'" "'&$mp3file&'"',@scriptdir, @SW_HIDE)
    consolewrite("Lame.exe exit code: "&$return & @crlf) 
    return $return
EndFunc

Thank you

Tuk

Link to comment
Share on other sites

Still can't make it work:

$wavfile = @scriptdir&"\input.wav"
$mp3file = @scriptdir&"\output.mp3"

func _wav2mp3($wavfile,$mp3file)
    $lameexe = @scriptdir&"\lame.exe"
    $lameoptions=""
    consolewrite("Encoding WAV file to MP3..."&@crlf)
    $return = runwait('"'&$lameexe&'" '&$lameoptions&' "'&$wavfile&'" "'&$mp3file&'"',@scriptdir, @SW_HIDE)
    consolewrite("Lame.exe exit code: "&$return & @crlf) 
    return $return
EndFunc

I also tried: $lameexe = @scriptdir&"\lame.exe" & $lameoptions=""

Thank you

Tuk

Link to comment
Share on other sites

After setting $wavfile and $mp3file, you're calling the function, right? Like this:

$wavfile = @scriptdir&"\input.wav"
$mp3file = @scriptdir&"\output.mp3"
_wav2mp3($wavfile,$mp3file)

func _wav2mp3($wavfile,$mp3file,$lameoptions="")
    $lameexe = @scriptdir&"\lame.exe"
    consolewrite("Encoding WAV file to MP3..."&@crlf)
    $return = runwait('"'&$lameexe&'" '&$lameoptions&' "'&$wavfile&'" "'&$mp3file&'"',@scriptdir, @SW_HIDE)
    consolewrite("Lame.exe exit code: "&$return & @crlf)
    return $return
EndFunc

Edited by lod3n

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Link to comment
Share on other sites

lod3n

Thank you for you patience and help. I am not expert but I try to learn.

It works perfect !!! :lmao:

The first scrip (no voice check) also works by replacing to this:

_text2mp3($text,$mp3file)

I assume this is a shortcut instead of removing unneeded lines, or the whole original UDF script is necessary ?

Thank you

Tuk

Edited by Tukata
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...