指定のテキストをTTS(Text To Speech)音声で読み上げ、読み上げ所要時間を計算するAppleScriptです。
実時間をかけて読み上げるのではなく、ファイルに対して音声レンダリングしたデータを書き込む動作をsayコマンドで行うため、読み上げ実時間よりも短い時間で動作を完了します。
読み上げ速度を遅いパターンと速いパターンで個別に音声レンダリングして所要時間のシミュレーションを行ったり、Keynoteのプレゼン資料のすべてのテキスト要素を読み上げ所要時間のシミュレーションを行なって、資料の枚数が多すぎるとか少なすぎるといった判断を行なっています(与えられた時間よりも多い資料を発表することはできないので)。
とくに、プレゼン発表に不慣れな人は発表資料のページを多くしがち&1ページあたりの文字数を多くしがちなので、sayコマンドによる読み上げシミュレーションで「この発表時間に対して要素が多すぎるのでは?」といった話をします。
AppleScript名:テキストをTTSで読み上げて所要時間を算出 v2.1(CotEditor版) |
— Created 2018-01-10 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AVFoundation" use framework "AppKit" –http://piyocast.com/as/archives/5113 property |NSURL| : a reference to current application’s |NSURL| property NSDate : a reference to current application’s NSDate property NSUUID : a reference to current application’s NSUUID property NSFileManager : a reference to current application’s NSFileManager property AVAudioPlayer : a reference to current application’s AVAudioPlayer property NSDateFormatter : a reference to current application’s NSDateFormatter property NSSpeechSynthesizer : a reference to current application’s NSSpeechSynthesizer set str3 to getEditorText() of me if str3 = false then return set aVoice to "Kyoko" –Check existence of TTS Voice name set vList to retAvailableTTSnames() of me if aVoice is not in vList then error "Wrong TTS Voice Name" set d1 to readTextByTTSVoiceAndReturnDuration(str3, aVoice, 180) of me –aSpeedRate is "Words per minute. 180 to 220" set d2 to readTextByTTSVoiceAndReturnDuration(str3, aVoice, 220) of me set outStr to (formatHMS(d1) of me & "/180 words per minute") & return & (formatHMS(d2) of me & "/220 words per minute") & return tell application "CotEditor" activate write to console outStr end tell on readTextByTTSVoiceAndReturnDuration(aStr as string, aVoice as string, aSpeedRate as integer) set aUUID to NSUUID’s UUID()’s UUIDString() as string –set aPath to (((path to temporary items from user domain) as string) & aUUID & ".aif") set aPath to (((path to desktop) as string) & aUUID & ".aif") set aPOSIX to POSIX path of aPath tell current application say aStr using aVoice saving to (aPOSIX) speaking rate aSpeedRate without waiting until completion end tell repeat 100000 times set aExt to NSFileManager’s defaultManager()’s fileExistsAtPath:aPOSIX if aExt as boolean = true then exit repeat delay "0.001" as real end repeat if aExt = false then error "No Sound file" set aDur to getDuration(aPath as alias) of me try do shell script "rm -f " & quoted form of POSIX path of aPath end try return aDur as real end readTextByTTSVoiceAndReturnDuration on getDuration(aFile) set aURL to |NSURL|’s fileURLWithPath:(POSIX path of aFile) repeat 1000 times set aAudioPlayer to AVAudioPlayer’s alloc()’s initWithContentsOfURL:aURL |error|:(missing value) set aRes to aAudioPlayer’s prepareToPlay() if aRes as boolean = true then exit repeat delay 0.5 end repeat if aRes = false then error "TTS sound output failed" set channelCount to aAudioPlayer’s numberOfChannels() set aDuration to aAudioPlayer’s duration() return aDuration as real end getDuration on retAvailableTTSnames() set outList to {} set aList to NSSpeechSynthesizer’s availableVoices() set bList to aList as list repeat with i in bList set j to contents of i set aInfo to (NSSpeechSynthesizer’s attributesForVoice:j) set aInfoRec to aInfo as record set aName to VoiceName of aInfoRec set the end of outList to aName end repeat return outList end retAvailableTTSnames on formatHMS(aTime) set aDate to NSDate’s dateWithTimeIntervalSince1970:aTime set aFormatter to NSDateFormatter’s alloc()’s init() —This formatter text is localized in Japanese. if aTime < hours then aFormatter’s setDateFormat:"mm分ss秒" else if aTime < days then aFormatter’s setDateFormat:"HH時間mm分ss秒" else aFormatter’s setDateFormat:"DD日HH時間mm分ss秒" end if set timeStr to (aFormatter’s stringFromDate:aDate) as string return timeStr end formatHMS on getEditorText() tell application "CotEditor" if (count every document) = 0 then return false tell front document return contents end tell end tell end getEditorText |