[H2] bing_Voice() - 使用必应的语音接口阅读文本
Posted: 16 Jul 2016, 10:08
相比股沟语音的口音,必应的更加顺耳.
有字数限制.
有字数限制.
Code: Select all
bing_Voice("Text reading")
bing_Voice("文本阅读")
bing_Voice("文本阅读 Text reading")
Code: Select all
bing_Voice(s){
static cookie
f:={head:head:=[]}
f.url:="http://www.bing.com/translator/api/language/Speak?locale=" (regexmatch(s, "[^\x00-\xff]")?"zh-CN":"en-US") "&gender=female&media=audio/mp3&text=" StrReplace(Uri_Encode(s),"`%20","+")
head["Host"]:="www.bing.com"
head["User-Agent"]:="Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0"
head["Accept"]:="audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5"
head["Accept-Language"]:="zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"
head["Range"]:="bytes=0-"
head["Referer"]:="http://www.bing.com/translator/?mkt=zh-CN"
head["Cookie"]:=(c:=cookie)?c:(cookie:=(y:=ir({gethead:1,url:"http://www.bing.com/translator/"}).allhead)?("MUIDB=" str_s(y,"MUIDB=",";") "; mtstkn=" str_s(y,"mtstkn=",";") "; "):"")
head["Connection"]:="keep-alive"
f.File:=A_temp "\temp_bing_" A_TickCount ".mp3"
if !ir(f).err
SoundPlay,% f.File
FileDelete,% f.File
}
ir(url,proxy:="",charset:=""){
static err := ComObjError(false)
,head := {"user-agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"}
this:=IsObject(url) ? url : {url:url, proxy:proxy, charset:charset},this.time:=A_TickCount
, this.Http:=http:=this.Http ? this.Http : ComObjCreate("WinHttp.WinHttpRequest.5.1")
, this.proxy ? http.setproxy(2, this.proxy) : 0
, this.page ? http.Option(2):=this.page : 0
, http.option(6) := this.NoRedirect ? 0 : 1
http.open(this.GetHead or (charset=0)?"head":this.post?"post" : "get",this.url,true)
if IsObject(this.head)
for i,n in head
this.head.HasKey(i)?"":this.head[i]:=n
else
this.head:=head
for i,n in this.head
http.SetRequestHeader(i,n)
((this.post) and !this.head["Content-Type"]
? http.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"):"")
(this.Progress and ((type(this.Progress)="BoundFunc") or this.Progress:=Func(this.Progress)))
,(this.Finished and ((type(this.Finished)="BoundFunc") or this.Finished:=Func(this.Finished)))
if this.Progress or this.Finished
{
this.CallBack:=[],this.SetCapacity("pUnk",A_PtrSize*8),Addres:=&this
,NumPut(this.GetAddress("pUnk")+A_PtrSize,pUnk:=this.GetAddress("pUnk"))
for i,n in ["query","addref","release","OnResponseStart","OnResponseDataAvailable","OnResponseFinished",this.OnError?this.OnError:"OnError"]
NumPut(this.CallBack[A_Index]:=RegisterCallback("ir_event_" n,"F",,Addres),pUnk+A_PtrSize*A_Index)
pCPC:=ComObjQuery(http,"{B196B284-BAB4-101A-B69C-00AA00341D07}"),VarSetCapacity(GUID,16,0)
,DllCall(NumGet(NumGet(pCPC+0,"ptr")+4*A_PtrSize,"ptr"),"ptr",pCPC,"ptr"
,DllCall("ole32\CLSIDFromString","wstr","{f97f4e15-b787-4212-80d1-d380cbbf982e}","ptr",&GUID)>= 0?&GUID:"","ptr*",pCP)
,DllCall(NumGet(NumGet(pCP+0,"ptr")+5*A_PtrSize,"ptr"),"ptr",pCP,"ptr",this.GetAddress("pUnk"),"uint*",Cookie)
this.__References:=this
}
(this.Timeout ? http.SetTimeouts(0, 60000, 30000, this.Timeout * 1000) : ""
,this.Tim:=Timeout:=this.Timeout = "" ? -1 : this.Timeout)
loop (this.try?this.try:1)
{
this.try_Index:=A_Index
http.send(this.post)
if (this.RetCode:=http.WaitForResponse(Timeout))=-1
Break
else if A_Index>=this.try
return this.err:=1,this
}
if this.Timeout = 0
return
this.Status:=http.Status,this.StatusText:=http.StatusText
if !this.AllHead
ir_head(this.AllHead:=http.getAllResponseHeaders(),this)
if this.gethead or (charset=0)
return this
return ir_process(this)
}
ir_process(this){
body := this.http.ResponseBody()
,VarSetCapacity(data, size:= body.Length() + 1)
,DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(body), "ptr*",pdata)
,RtlMoveMemory(&data, pdata, size)
,DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(body))
this.Size:=size
if (this.Size_Detect or this.file or this.bin) and (!this["Content-Length"] or (Size!=this["Content-Length"]))
return this.err:="Size Err",this
InStr(this["Content-Encoding"],"gzip") ? Size:=ir_gzip(data, Size) : ""
this.time:=A_TickCount-this.time
return (this.Size:=Size)?(this.file
? (FileExist(dir:=SubStr(this.File,1,InStr(this.File,"\","",-1)))?"":DirCreate(dir)
,FileOpen(this.AuName OR this.AuExt ?ir_AuName(this):this.file, "w").RawWrite(&data, size),this)
: (this.bin)
?(this.Delete("Bin"),this.SetCapacity("Bin",Size),RtlMoveMemory(this.GetAddress("Bin"),&data,Size),this)
: ((encoding:=this.charset?this.charset:"UTF-8")
,(s:=StrGet(&data, size>>(encoding="utf-16"||encoding="cp1200"),encoding))
,!this.charset and (encoding!=r:=(i:=InStr(SubStr(s,1,300),"charset=")) and (i:=Trim(SubStr(s, e:=i+8,RegExMatch(s,"`'|`"|>|//",,i+9)-e),"`'`"/")) ? InStr(i,"gb")?"CP936":i:"UTF-8")
? (s:=StrGet(&data, size>>(r="utf-16"||r="cp1200"),R)):"",this.Decode?s:=Decode_All(s):1
,this.text:=s,this.json and RegExMatch(s, "s)^[\[|\{].*[\]|\}]$") ? this.json:=so(s,0):"",(this.result ? this : s))):(this.err:=2,this)
}
ir_event_query(self,riid,pObj){
return NumPut(self,pObj+0)*0
}
ir_AuName(this){
if (s:=this["Content-Disposition"]) and r:=InStr(s, "filename=")
name:=SubStr(s, i:=r+10,InStr(s, "`"",,i)-i)
if this.AuName
return this.filename:=this.File "\" (name ?name: this.AuName)
if this.AuExt
{
s:=this["Content-Type"]
if !Ext:=SubStr(name, InStr(name,".",, -1)+1)
Ext:=SubStr(s, i:=InStr(s, "/")+1,(r:=InStr(s, ";"))?r-i:22)
return this.filename:=this.File "." (Ext ?Ext: this.AuExt)
}
}
ir_event_addref(self){
return 1
}
ir_event_release(self){
return 0
}
ir_event_OnResponseStart(self,Status,ContentType){
static code:={200:"OK",404:"Not Found"}
this:=Object(A_eventInfo)
if this.nohead
Return
ir_head(this.AllHead:=this.http.getAllResponseHeaders(),this)
,((i:= Round(this["Content-Length"]/1024)) < 1024) ?(this.Promptl_Units:=1024,this.Promptl_Len:= "/" i " K") : (this.Promptl_Units:=1048576,this.Promptl_Len:= "/" Round(i/1024, 1) " M")
,DllCall("QueryPerformanceFrequency","Int64*",Frequency)
,DllCall("QueryPerformanceCounter","Int64*",Counter)
,this.ResponseStart := code[status]?code[status]:Status
,this.Current_Len := 0
,this.event_Frequency := Frequency
,this.event_Counter := this.event_Counter0 :=Counter
}
ir_event_OnResponseDataAvailable(self,Data){
this:=Object(A_eventInfo)
if this.nohead
Return
SafeArrayGetUBound(NumGet(Data,"PTR"),1,getvar(sz:=0))
this.Current_Len+=sz + 1
DllCall("QueryPerformanceCounter", "Int64*", Counter)
time:=(Counter-this.event_Counter)/this.event_Frequency
if (time>=1)
{
this.event_Counter:=Counter
if this.Progress
this.Progress.call({this:this,name:"Progress",total:this["Content-Length"],Current:this.Current_Len,process:Round(this.Current_Len/this.Promptl_Units,1) this.Promptl_Len
,scale:(Round(this.Current_Len/this["Content-Length"]*100,1) " `%"),speed:(Round((((this.Current_Len-this.Current_Mark)/1024)/time)) " KB"),title:this.title})
this.Current_Mark:=this.Current_Len
}
}
ir_event_OnResponseFinished(self){
this:=Object(A_eventInfo)
this.Delete("__References")
if this.Progress
this.Progress.call({this:this,name:"Finished",self:self,title:this.title})
if this.Timeout=0
ir_process(this)
if this.Finished
this.Finished.call(this,222)
for k,v in this.Delete("CallBack")
GlobalFree(v)
return
}
ir_event_OnError(self,ErrorNumber,ErrorDescription){
this:=Object(A_eventInfo)
if this.Func
this.Func.call({this:this,name:"Error",self:self,ErrorNumber:ErrorNumber,ErrorDescription:ErrorDescription})
}
ir_head(ByRef Header,ByRef this){
Loop,parse,% Header,`n,`r `t
(s:=InStr(A_LoopField,":"))
? (this[p:=SubStr(A_LoopField, 1,s-1)]?(this[p].="; " Trim(SubStr(A_LoopField, s+1))):(this[p]:=Trim(SubStr(A_LoopField, s+1))))
: this[A_LoopField]:=""
}
ir_gzip(ByRef var, nSz:=0){
static Module
if !DllCall("GetModuleHandle", "Str",r:=A_ahkDir "\Extend\Library\gzip.dll", "Ptr")
DllCall("LoadLibrary","Str",r, "Ptr")
vSz := NumGet( var,nsz-4 ), VarSetCapacity( out,vsz,0)
,DllCall( "GZIP\InitDecompression" ),DllCall( "GZIP\CreateDecompression", UIntP,CTX, UInt,1 )
If ( DllCall( "GZIP\Decompress", UInt,CTX, UInt,&var, UInt,nsz, UInt,&Out, UInt,vsz, UIntP,input_used, UIntP,output_used ) = 0 && ( Ok := ( output_used = vsz ) ) )
VarSetCapacity( var,64 ), VarSetCapacity( var,0 ), VarSetCapacity( var,vsz,32 ), RtlMoveMemory(&var,&out,vsz )
DllCall( "GZIP\DestroyDecompression", UInt,CTX ), DllCall( "GZIP\DeInitDecompression" )
Return Ok ? vsz : 0
}
so(s,n:=""){
static json,jx,d,y:="`"",j:="`" `t",m:={"\b":Chr(08),"\\":"\","\t":"`t","\n":"`n","\f":Chr(12),"\r":"`r"},gu:="āЁξ"
if Isobject(s)
{
if !InStr(Type(s),"Object")
Return
if !Count:=s.Count()
Return "[]"
if w:= (Count = s.Length())
for k in s
if (k != A_Index)
{
w:=""
Break
}
if w
{
for i,n in s
str.=(Type(n)="Object"?so(n,1): n+0=""?(gu n gu):n) ","
}
else
{
for i,n in s
str.=(Type(i)="Object"?so(i,1):i+0=""?(gu i gu):i) ":" (Type(n)="Object"?so(n,1): n+0=""?(gu n gu):n) ","
}
if !n
{
if n=0
{
StrReplace, str, %str%,% "`n",% "``n"
StrReplace, str, %str%,% y,% "``" y
StrReplace, str, %str%,% gu,% y
}
else
{
StrReplace, str, %str%,/,\/
for c,z in m
IF InStr(str,z)
StrReplace, str, %str%,% z,% c
StrReplace, str, %str%,% y,% "\" y
StrReplace, str, %str%,% gu,% y
}
}
Return str:=RTrim(str,","),w?"[" str "]":"{" str "}"
}
f:=[],i:=1
if n
b:=StrLen(s)
else
{
if !(s:=Trim(s," `n`r`t")) or !regexmatch(s, "[\[\{]")
Return s
if json:=(n=0) ; so(s,0) json
{
for c,z in m
if InStr(s,c)
StrReplace,s,% s,% c,% z
StrReplace, s, %s%,\/,/
if e:=InStr(s,"\u")
for e,n in StrSplit(SubStr(s, e+2), "\u")
IF n and !f[b:=SubStr(n, 1, 4)]
{
IF d := Abs("0x" b)
StrReplace,s,% s,% "\u" b,% Chr(d)
f[b]:=1
}
}
f:=[],b:=StrLen(s),n:=SubStr(s,i,1),d:=0,jx:=json?"\":"``"
}
if (n="{")
loop
{
if ((r?r[0]:"") = "}") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "}")
Return d:=i,f
if InStr("[{",n)
(k:=so(SubStr(s,i),n),i+=d,i:=RegExMatch(s,"\S",t,InStr(s,":",,i)+1),(InStr("[{",t:=i?t[0]:"")
? (f[so_json(K,json) ""]:=so(SubStr(s,i),t),i:=RegExMatch(s,",|\}",r,i+d))
: ( ((t=y) ? (p:=InStr(s,y,,i+1),p:=RegExMatch(s,",|\}",r,p),z:=Trim(SubStr(s,i+1,p-i-2)))
: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0))
,f[so_json(K,json) ""]:=so_json(K,json),i:=p)) )
else
(x:=InStr(s,":",,(n=y)?InStr(s,y,,i,2):i))
? (k:= ((n=y)?SubStr(s,i+1,x-i-2):SubStr(s,i,x-i))
,k:=(n=y ? Trim(k) : n="(" ? so_Try(Trim(k,"() `t")):Trim(k)),i:=RegExMatch(s,"\S",t,x+1)
,InStr("[{",t:=i?t[0]:"")
? (f[so_json(K,json) ""]:=so(SubStr(s,i),t),i:=RegExMatch(s,",|\}",r,i+d))
: ( ((t=y) ? (p:=RegExMatch(s,",|\}",r,so_InStr(s,i,jx)),z:=Trim(SubStr(s,i+1,InStr(s,y,,p-b-1)-i-1)))
: (p:=RegExMatch(s,",|\}",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0))
,f[so_json(K,json) ""]:=so_json(Z,json),i:=p))
: i:=0
}
if (n = "[")
loop
{
if ((r?r[0]:"") = "]") or !i or !( i:=RegExMatch(s,"\S",n,i+1) ) or ((n:=n[0]) = "]")
Return d:=i,f
(InStr("[{",n)
? (f.Push(so(SubStr(s,i),n)),i:=RegExMatch(s,",|\]",r,i+d))
: ( (n=y) ? (p:=RegExMatch(s,",|\]",r,so_InStr(s,i,jx)),z:=Trim(SubStr(s,i+1,InStr(s,y,,p-b-1)-i-1)))
: (p:=RegExMatch(s,",|\]",r,i),z:=Trim(SubStr(s,i,p-i)),z:=z+0=""?so_Try(z):z+0),i:=p
,f.Push(so_json(Z,json))))
}
}
so_json(s,json){
static J:="\`"",P:="`""
Return json AND InStr(s,J)?StrReplace(S,J,P):S
}
so_InStr(s,i,jx){
while (p:=InStr(s,"`"",,i+1)) and (SubStr(s,p-1,1)=jx)
i:=p
Return p
}
so_Try(f){
global
Try
Return (%f%)
}
Decode_Html(ByRef str){
oscs := A_StringCaseSense
StringCaseSense, On
Loop, Parse,% "middot,·/nbsp, /#160, /lt,</#60,</gt,>/#62,>/amp,&/#38,&/quot,`"/#34,`"/apos,`'/#39,`'/cent,¢/#162,¢/pound,£/#163,£/yen,¥/#165,¥/euro,€/#8364,€/sect,§/#167,§/copy,©/#169,©/reg,®/#174,®/trade,™/#8482,™/times,×/#215,×/divide,÷/#247,÷/OElig,Œ/oelig,œ/Scaron,Š/scaron,š/Yuml,Ÿ/fnof,ƒ/circ,ˆ/tilde,˜/Alpha,Α/Beta,Β/Gamma,Γ/Delta,Δ/Epsilon,Ε/Zeta,Ζ/Eta,Η/Theta,Θ/Iota,Ι/Kappa,Κ/Lambda,Λ/Mu,Μ/Nu,Ν/Xi,Ξ/Omicron,Ο/Pi,Π/Rho,Ρ/Sigma,Σ/Tau,Τ/Upsilon,Υ/Phi,Φ/Chi,Χ/Psi,Ψ/Omega,Ω/alpha,α/beta,β/gamma,γ/delta,δ/epsilon,ε/zeta,ζ/eta,η/theta,θ/iota,ι/kappa,κ/lambda,λ/mu,μ/nu,ν/xi,ξ/omicron,ο/pi,π/rho,ρ/sigmaf,ς/sigma,σ/tau,τ/upsilon,υ/phi,φ/chi,χ/psi,ψ/omega,ω/thetasym,ϑ/upsih,ϒ/piv,ϖ/ensp, /emsp, /thinsp, /zwnj,/zwj,/lrm,/rlm,/ndash,–/mdash,—/lsquo,‘/rsquo,’/sbquo,‚/ldquo,“/rdquo,”/bdquo,„/dagger,†/Dagger,‡/bull,•/hellip,…/permil,‰/prime,′/Prime,″/lsaquo,‹/rsaquo,›/oline,‾/frasl,⁄/euro,€/image,ℑ/weierp,℘/real,ℜ/trade,™/alefsym,ℵ/larr,←/uarr,↑/rarr,→/darr,↓/harr,↔/crarr,↵/lArr,⇐/uArr,⇑/rArr,⇒/dArr,⇓/hArr,⇔/forall,∀/part,∂/exist,∃/empty,∅/nabla,∇/isin,∈/ni,∋/prod,∏/sum,∑/minus,−/lowast,∗/radic,√/prop,∝/infin,∞/ang,∠/and,∧/or,∨/cap,∩/cup,∪/int,∫/there4,∴/sim,∼/cong,≅/asymp,≈/ne,≠/equiv,≡/le,≤/ge,≥/sub,⊂/sup,⊃/nsub,⊄/sube,⊆/supe,⊇/oplus,⊕/otimes,⊗/perp,⊥/sdot,⋅/lceil,⌈/rceil,⌉/lfloor,⌊/rfloor,⌋/lang,⟨/rang,⟩/loz,◊/spades,♠/clubs,♣/hearts,♥/diams,♦", /
(InStr(str,i:="&" SubStr(s,1,(r:=InStr(s:=A_LoopField,","))-1) ";")?str:=StrReplace(str,i,SubStr(s,r+1)):"")
Return StringCaseSense(oscs),str
}
Decode_Escape(ByRef str){
f:=[]
if i:=InStr(str,"\u")
for i,n in StrSplit(SubStr(str,i+2),"\u")
(n and !f[b:=SubStr(n, 1, 4)]
? (f[b]:=1,(s := Abs("0x" b))?(str:=StrReplace(str,"\u" b,Chr(s))):"")
: "")
return str
}
Decode_Ascii(ByRef str){
Loop, Parse,01|02|03|04|05|06|07|08|09|0a|0b|0c|0d|0e|0f|10|11|12|13|14|15|16|17|18|19|1a|1b|1c|1d|1e|1f|20|21|22|23|24|25|26|27|28|29|2a|2b|2c|2d|2e|2f|30|31|32|33|34|35|36|37|38|39|3a|3b|3c|3d|3e|3f|40|41|42|43|44|45|46|47|48|49|4a|4b|4c|4d|4e|4f|50|51|52|53|54|55|56|57|58|59|5a|5b|5c|5d|5e|5f|60|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|78|79|7a|7b|7c|7d|7e|7f,|
InStr(str,"\x" A_LoopField)?str:=StrReplace(str,"\x" A_LoopField,Chr("0x" A_LoopField)):""
return str
}
Decode_All(ByRef str){
return Decode_Html(Decode_Escape(Decode_Ascii(str)))
}
Uri_Encode(str){
n := StrPutVar(str, UTF8, "UTF-8"),f:={"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":1,"68":1,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"2d":1,"2e":1,"4a":1,"4b":1,"4c":1,"4d":1,"4e":1,"4f":1,"5a":1,"5f":1,"6a":1,"6b":1,"6c":1,"6d":1,"6e":1,"6f":1,"7a":1,"7e":1}
loop, strlen(hex:=BintoHex(&UTF8,n))/2-1
Res .= f[r:=substr(hex, A_index*2-1,2)]?Chr("0x" r):"`%" r
return Res
}
str_s(ByRef s,i,n,r:=1){ ;single
Return SubStr(s,u:=InStr(s,i,,,r)+StrLen(i),InStr(s,n,,u)-u)
}