PageSourceSearch

https://www.jkingstools.com/npublic/commonjs/nouglify/bdAudio.js

js jkingstools.com collected 2026-10-04 04:48:14 UTC 11,048 bytes, 303 lines download raw bytes

1(function (root, factory) {
2	if (typeof define === 'function' && define.amd) {
3		define([], factory);
4	} else if (typeof module === 'object' && module.exports) {
5		module.exports = factory();
6	} else {
7		root.AudioPlayer = factory();
8	}
9})(this, function () {
10	'use strict';
11    class AudioPlayer {
12        constructor() {
13            this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
14            this.sourceNode = null;
15            this.audioBuffer = null;
16            this.startTime = 0;
17            this.pauseTime = 0;
18            this.isPlaying = false;
19            this._onEnded = this._handleEnded.bind(this);
20            
21            this.playlist = [];
22            this.currentIndex = 0;
23            this.onTrackEnd = null;
24            this.onPlaylistEnd = null;
25        }
26        async loadAudio(url) {
27            const response = await fetch(url);
28            const arrayBuffer = await response.arrayBuffer();
29            this.audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
30        }
31        _handleEnded() {
32            if (this.isPlaying) {
33                this.isPlaying = false;
34                this.pauseTime = 0;
35                this.sourceNode = null;
36                
37                if (this.onTrackEnd) {
38                    this.onTrackEnd(this.playlist[this.currentIndex]);
39                }
40                
41                this.currentIndex++;
42                if (this.currentIndex < this.playlist.length) {
43                    this.loadAndPlay(this.playlist[this.currentIndex]);
44                } else if (this.onPlaylistEnd) {
45                    this.onPlaylistEnd();
46                }
47            }
48        }
49        async loadAndPlay(url) {
50            try {
51                await this.loadAudio(url);
52                this.play();
53            } catch (error) {
54                console.error(`加载 ${url} 失败:`, error);
55                // 即使失败也继续播放下一个
56                this._handleEnded();
57            }
58        }
59        setPlaylist(tracks, startIndex = 0) {
60            this.playlist = tracks;
61            this.currentIndex = startIndex;
62        }
63        startPlaylist() {
64            if (this.playlist.length > 0) {
65                this.currentIndex = 0;
66                this.loadAndPlay(this.playlist[0]);
67            }
68        }
69        play() {
70            if (!this.audioBuffer) return;
71            // 如果已暂停,从暂停位置继续
72            const offset = this.pauseTime || 0;
73            // 创建新节点
74            this.sourceNode = this.audioContext.createBufferSource();
75            this.sourceNode.buffer = this.audioBuffer;
76            this.sourceNode.connect(this.audioContext.destination);
77            // 设置结束回调(注意不要用匿名函数,方便移除)
78            this.sourceNode.onended = this._onEnded;
79            this.startTime = this.audioContext.currentTime - offset;
80            this.sourceNode.start(0, offset);
81            this.isPlaying = true;
82            this.pauseTime = 0;
83        }
84        pause() {
85            if (!this.isPlaying) return;
86            // 临时移除结束回调
87            this.sourceNode.onended = null;
88            // 停止播放
89            this.sourceNode.stop();
90            this.sourceNode = null;
91            // 记录暂停位置
92            this.pauseTime = this.audioContext.currentTime - this.startTime;
93            this.isPlaying = false;
94            console.log('已暂停,位置:', this.pauseTime);
95        }
96        stop() {
97            if (this.sourceNode) {
98                // 临时移除结束回调
99                this.sourceNode.onended = null;
100                this.sourceNode.stop();
101                this.sourceNode = null;
102            }
103            this.isPlaying = false;
104            this.pauseTime = 0;
105        }
106        togglePlayPause() {
107            if (this.isPlaying) {
108                this.pause();
109            } else {
110                this.play();
111            }
112        }
113        // 其他实用方法
114        get currentTime() {
115            if (this.isPlaying) {
116                return this.audioContext.currentTime - this.startTime;
117            }
118            return this.pauseTime || 0;
119        }
120        get duration() {
121            return this.audioBuffer ? this.audioBuffer.duration : 0;
122        }
123        // 销毁时释放资源
124        dispose() {
125            this.stop();
126            if (this.audioContext.state !== 'closed') {
127                this.audioContext.close();
128            }
129        }
130    }
131  	return AudioPlayer;
132});
133$define(['cmsAjax',"/npublic/commonjs/jsencrypt.js","md5"],function(c,rsa,a) {
134    $.extend({
135        bdAudio: function(options) {
136            if(typeof options == "string"){
137                options = {
138                    text:options
139                }
140            }
141            var obj = $.extend({
142                text:"",
143                lan:'zh',
144                cuid:'ypsm',
145                ctp:1,
146                spd:7,
147                onEnd:function(){},
148                onError:function(){}
149            },options)
150            if(!obj.text){
151                return
152            }
153            let cText = []
154            let element = $("body")
155            let ttsAudio = null
156            let env = getBrowserEnv()
157            let sourcePlayer = null
158            if(env.isAndroidWeixin){
159                sourcePlayer = new AudioPlayer();
160            }
161            let token = sessionStorage.getItem("bdAudioToken")
162            if(!token){
163                getToken(function(){
164                    renderText(obj.text)
165                })
166            }else{
167                renderText(obj.text)
168            }
169            // 获取浏览器环境
170            function getBrowserEnv() {
171                const ua = navigator.userAgent.toLowerCase();
172                return {
173                    isWeixin: /micromessenger/.test(ua),
174                    isAndroid: /android/.test(ua),
175                    isIOS: /(iphone|ipad|ipod|ios)/.test(ua),
176                    isX5: /tbs/.test(ua) || /mqqbrowser/.test(ua),
177                    isAndroidWeixin: /micromessenger/.test(ua) && /android/.test(ua)
178                };
179            }
180            // 获取token
181            function getToken(callback){
182                let url = "/fwebapi/visitor/lowcode/intelligent/audio/getAudioToken"
183                let p = $.nrsa(`designVue&${$.md5(navigator.userAgent)}`,'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdBbSMUKBY3wW8C/RFFwFoTHyO8xM67xBtgERb/4z6dqUq2ZeTagHUT6tbnuvhug0FNU9t/bzBc6KOivkzPToYYJG/RDzvdAJTjdvvvu3WQUpKOa0s0V3ehkKRoZPIFw3YnahtUrIe9es0V0LlTkOyFlH2M6rpceC7K0XgEs7lZwIDAQAB')
184                c.cmsAjax.get(url,{},{headers:{authCode:p}}).then((res)=>{
185                    if(res && res.data && res.data.token){
186                        sessionStorage.setItem("bdAudioToken",res.data.token)
187                        token = sessionStorage.getItem("bdAudioToken")
188                        callback()
189                    }
190                })
191            }
192            // 解析文本,分隔成数组
193            function renderText(text){
194                if($(".ttsAudio").length>0){
195                    $(".ttsAudio").remove()
196                }
197                let tArr = []
198                if(text.length>60){
199                    tArr = text.split(/[。:;\n]/)
200                }else{
201                    tArr.push(text)
202                }
203                tArr = tArr.filter(item => item.trim()!== '').map(item => item.trim());
204                cText = tArr
205                console.log(cText)
206                cText.forEach(e=>{
207                    console.log(e.length,e)
208                })
209                if(env.isAndroidWeixin){
210                    let audioList = []
211                    cText.forEach(e=>{
212                        let url = getAudio(e)
213                        audioList.push(url)
214                    })
215                    sourcePlayer.stop();
216                    sourcePlayer.setPlaylist(audioList);
217                    sourcePlayer.onTrackEnd = (trackUrl) => {
218                        // console.log(`已完成播放: ${trackUrl}`);
219                    };
220                    sourcePlayer.onPlaylistEnd = () => {
221                        console.log('播放列表全部播放完毕');
222                        nowId = ""
223                    };
224                    sourcePlayer.startPlaylist();
225                    return
226                }else{
227                    processQueue(true)
228                }
229            }
230            // 队列渲染
231            function processQueue(k){
232                if(cText.length==0){
233                    console.log('队列完成')
234                    obj.onEnd()
235                    playFirst()
236                    return
237                }
238                let item = cText.shift()
239                let item2 = null
240                if(k){
241                    item2 = cText.shift()
242                }
243                read(item,item2).then(()=>{
244                    processQueue()
245                })
246            }
247            // 异步插入音频,并控制播放
248            function read(text,text2){
249                return new Promise((resolve, reject) => {
250                    appendAudio(text)
251                    if(text2){
252                        appendAudio(text2)
253                    }
254                    playFirst(resolve)
255                });
256            }
257            // 插入音频
258            function appendAudio(text){
259                let url = getAudio(text)
260                const audio = document.createElement('audio');
261                audio.className = 'ttsAudio';
262                audio.src = url;
263                audio.preload = 'auto';
264                element.append(audio)
265            }
266            // 获取音频地址
267            function getAudio(text){
268                let data = {
269                    token:token,
270                    tex:encodeURIComponent(encodeURIComponent(text)),
271                    lan:obj.lan,
272                    cuid:obj.cuid,
273                    ctp:obj.ctp,
274                    spd:obj.spd
275                }
276                let arr = []
277                for(let i in data){
278                    arr.push(`${i}=${data[i]}`)
279                }
280                let url = `${__ce.baseURL}/fwebapi/visitor/lowcode/intelligent/audio/getAudioData?${arr.join('&')}`
281                return url
282            }
283            // 播放音频
284            function playFirst(resolve){
285                ttsAudio = element.find('.ttsAudio')[0];
286                if (ttsAudio) {
287                    ttsAudio.play();
288                    ttsAudio.addEventListener('ended',()=>{
289                        $(ttsAudio).remove();
290                        if(resolve){
291                            resolve()
292                        }
293                    });
294                    ttsAudio.addEventListener('error',()=>{
295                        getToken(function(){
296                            renderText(obj.text)
297                        })
298                    });
299                }
300            }
301        }
302    })
303})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.