@@ -25,6 +25,28 @@ | |||
}, | |||
methods: { | |||
// 时分秒转换为秒 | |||
TIMEEVENT(e) { | |||
var time = e; | |||
var len = time.split(':') | |||
if (len.length == 3) { | |||
var hour = time.split(':')[0]; | |||
var min = time.split(':')[1]; | |||
var sec = time.split(':')[2]; | |||
return Number(hour * 3600) + Number(min * 60) + Number(sec); | |||
} | |||
if (len.length == 2) { | |||
var min = time.split(':')[0]; | |||
var sec = time.split(':')[1]; | |||
return Number(min * 60) + Number(sec); | |||
} | |||
if (len.length == 1) { | |||
var sec = time.split(':')[0]; | |||
return Number(sec); | |||
} | |||
}, | |||
// 目前使用页面为录音页面 | |||
SPEAKERSTYLE(index) { | |||
let obj = { | |||
@@ -138,8 +160,8 @@ | |||
let pushon = uni.getStorageSync('weapp_session_userInfo_data').loginName | |||
uni.connectSocket({ | |||
url: 'wss://hfju.com/ws?uid=' + pushon + '_applets', | |||
header: { | |||
"content-type": "application/json", | |||
header: { | |||
"content-type": "application/json", | |||
'Access-Token': uni.getStorageSync('weapp_session_login_data').token | |||
} | |||
}); | |||
@@ -0,0 +1,10 @@ | |||
export declare function formatSeconds(seconds: number | string): string; | |||
export declare function throttle(fn: Function, wait: number): Function; | |||
export declare class EventBus { | |||
private _events; | |||
constructor(); | |||
protected on(event: any, action: any, fn: () => {}): void; | |||
private has; | |||
protected emit(event: any, data?: any): void; | |||
protected off(event: any, action: any): void; | |||
} |
@@ -0,0 +1,73 @@ | |||
"use strict"; | |||
Object.defineProperty(exports, "__esModule", { | |||
value: true | |||
}); | |||
exports.EventBus = exports.throttle = exports.formatSeconds = void 0; | |||
function formatSeconds(seconds) { | |||
var result = typeof seconds === "string" ? parseFloat(seconds) : seconds; | |||
if (isNaN(result)) return ""; | |||
let h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600); | |||
let m = Math.floor((result / 60) % 60) < 10 ? "0" + Math.floor((result / 60) % 60) : Math.floor((result / 60) % 60); | |||
let s = Math.floor(result % 60) < 10 ? "0" + Math.floor(result % 60) : Math.floor(result % 60); | |||
return `${h}:${m}:${s}`; | |||
//time为毫秒数 | |||
} | |||
exports.formatSeconds = formatSeconds; | |||
function throttle(fn, wait) { | |||
let previous = 0; | |||
return function(...arg) { | |||
let context = this; | |||
let now = Date.now(); | |||
//每隔一段时间执行一次; | |||
if (now - previous > wait) { | |||
fn.apply(context, arg); | |||
previous = now; | |||
} | |||
}; | |||
} | |||
exports.throttle = throttle; | |||
class EventBus { | |||
constructor() { | |||
this._events = new Map(); | |||
} | |||
on(event, action, fn) { | |||
let arr = this._events.get(event); | |||
let hasAction = arr ? | |||
arr.findIndex((i) => i.action == action) : | |||
-1; | |||
if (hasAction > -1) { | |||
return; | |||
} | |||
this._events.set(event, [ | |||
...(this._events.get(event) || []), | |||
{ | |||
action, | |||
fn, | |||
}, | |||
]); | |||
} | |||
has(event) { | |||
return this._events.has(event); | |||
} | |||
emit(event, data) { | |||
if (!this.has(event)) { | |||
return; | |||
} | |||
let arr = this._events.get(event); | |||
arr.forEach((i) => { | |||
i.fn(data); | |||
}); | |||
} | |||
off(event, action) { | |||
if (!this.has(event)) { | |||
return; | |||
} | |||
let arr = this._events.get(event); | |||
let newdata = arr.filter((i) => i.action !== action); | |||
this._events.set(event, [...newdata]); | |||
} | |||
} | |||
exports.EventBus = EventBus; |
@@ -0,0 +1,213 @@ | |||
interface audio { | |||
src: string; | |||
title: string; | |||
singer: string; | |||
coverImgUrl: string; | |||
} | |||
interface audioInfo extends audio { | |||
current: string; | |||
duration: string; | |||
duration_value: number; | |||
current_value: number; | |||
} | |||
declare enum zaudioCbName { | |||
onWaiting = "waiting", | |||
onError = "error", | |||
onTimeUpdate = "playing", | |||
onCanplay = "canPlay", | |||
onPause = "pause", | |||
onEnded = "ended", | |||
setAudio = "setAudio", | |||
updateAudio = "updateAudio", | |||
seek = "seek", | |||
onStop = "stop", | |||
syncStateOn = "syncStateOn" | |||
} | |||
import { EventBus } from "./util"; | |||
/** | |||
* ZAudio类 | |||
* @class ZAudio | |||
* @constructor | |||
* @param {String} defaultCover 音频默认封面 | |||
* @param {Boolean} continuePlay 继续播放,错误播放或结束播放后执行 | |||
* @param {Boolean} autoPlay 自动播放,部分浏览器不支持 | |||
* @property {Number} renderIndex 当前渲染索引 | |||
* @property {<audioinfo>} renderinfo 当前渲染数据 | |||
* @property {Array<audio>} audiolist 音频列表数组 | |||
* @property {<audioinfo>} playinfo 当前播放数据 | |||
* @property {Boolean} paused 音频暂停状态 | |||
* @property {Number} playIndex 当前播放索引 | |||
* @property {Boolean} renderIsPlay 渲染与播放是否一致 | |||
* | |||
* @method on(event, action, fn) 回调函数注册业务事件 | |||
* @method off(event, action) 回调函数中卸载业务事件 | |||
* @method setRender(data) 指定音频, 渲染到zaudio组件 | |||
* @method syncRender() 同步并渲染当前的播放状态 | |||
* @method operate(index) 播放或暂停指定索引的音频 | |||
* @method setAudio(list) 覆盖音频列表 | |||
* @method updateAudio(list) 添加音频列表 | |||
* @method stop() 强制暂停当前播放音频 | |||
* @method stepPlay(count) 快进快退 | |||
* @method syncStateOn(action, cb) 注册一个用于同步获取当前播放状态的事件 | |||
* @method syncStateOff(action) 卸载用于同步获取当前播放状态的事件 | |||
* | |||
* | |||
* **/ | |||
export default class ZAudio extends EventBus { | |||
static version: string; | |||
loading: boolean; | |||
renderIndex: number; | |||
audiolist: Array<audio>; | |||
renderinfo: audioInfo; | |||
playinfo: audioInfo; | |||
paused: boolean; | |||
uPause: boolean; | |||
audioCtx: any; | |||
autoPlay: boolean; | |||
defaultCover: string; | |||
continuePlay: boolean; | |||
constructor(options: { | |||
defaultCover: string; | |||
autoPlay: boolean; | |||
continuePlay: boolean; | |||
}); | |||
private init; | |||
checkEventParams(event: zaudioCbName, action: string | symbol, fn?: () => {}): boolean; | |||
/** | |||
* @description 回调中卸载业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @returns undefined | |||
* **/ | |||
off(event: zaudioCbName, action: string | symbol): void; | |||
/** | |||
* @description 回调中注册业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @param {function(object|string|number|undefined):undefined} fn 业务函数, 参数或为音频状态 | |||
* @returns undefined | |||
* **/ | |||
on(event: zaudioCbName, action: string | symbol, fn: () => {}): void; | |||
/** | |||
* @description 订阅触发音频回调 | |||
* @param {<zaudioCbName>} event 回调名称枚举值,具体看zaudioCbName | |||
* @param {object|string|number|undefined} data 订阅触发回调时,传的音频属性 | |||
* @returns undefined | |||
* **/ | |||
emit(event: zaudioCbName, data?: any): void; | |||
private commit; | |||
private onWaitingHandler; | |||
private onCanplayHandler; | |||
private onPlayHandler; | |||
private onPauseHandler; | |||
private onStopHandler; | |||
private onEndedHandler; | |||
private throttlePlaying; | |||
private onTimeUpdateHandler; | |||
private onErrorHandler; | |||
/** | |||
* @description 实时渲染当前状态 | |||
* @returns undefined | |||
* **/ | |||
syncRender(): void; | |||
/** | |||
* @description 注册一个实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @param {Funtion} fn 实时获取ZAudio属性回调 | |||
* @returns undefined | |||
* **/ | |||
syncStateOn(action: string, fn: () => {}): void; | |||
/** | |||
* @description 卸载实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @returns undefined | |||
* **/ | |||
syncStateOff(action: string): void; | |||
/** | |||
* @description 订阅实时获取ZAudio属性的方法 | |||
* @returns undefined | |||
* **/ | |||
private syncStateEmit; | |||
/** | |||
* @description 跳转播放 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
seek(value: number): void; | |||
/** | |||
* @description 快进 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
stepPlay(value: number): void; | |||
/** | |||
* @description 获取下一首歌曲索引(用于渲染和播放) | |||
* @param {Number} count 切换数量 | |||
* @returns number | |||
* **/ | |||
private getNextKey; | |||
/** | |||
* @description 切歌 | |||
* @param {Number} count 数量 | |||
* @returns undefined | |||
* **/ | |||
changeplay(count: number): void; | |||
/** | |||
* @description 手动播放或暂停, 并渲染对应的数据 | |||
* @param {Number|String|<audioInfo>|undefined} key 索引或音频对象 | |||
* @returns undefined | |||
* **/ | |||
operate(key?: number | string | audioInfo): void; | |||
/** | |||
* @description 强制暂停播放 | |||
* @returns undefined | |||
* **/ | |||
stop(): void; | |||
private operation; | |||
/** | |||
* @description 覆盖音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
setAudio(data: Array<audio>): void; | |||
/** | |||
* @description 添加音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
updateAudio(data: Array<audio>): void; | |||
/** | |||
* @description 设置当前播放信息 | |||
* @param {<audioInfo>} data 音频对象 | |||
* @returns undefined | |||
* **/ | |||
setPlayinfo<T extends keyof audioInfo>(data: audioInfo): void; | |||
/** | |||
* @description 设置暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setPause(data: boolean): void; | |||
/** | |||
* @description 设置loading | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setLoading(data: boolean): void; | |||
/** | |||
* @description 设置通话时暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setUnnormalPause(data: boolean): void; | |||
/** | |||
* @description 设置渲染 | |||
* @param {number | string | audioInfo} data 索引或渲染信息 | |||
* @returns undefined | |||
* **/ | |||
setRender(data: number | string | audioInfo): void; | |||
get playIndex(): number; | |||
get renderIsPlay(): boolean; | |||
private appCheckReplay; | |||
} | |||
export {}; |
@@ -0,0 +1,630 @@ | |||
"use strict"; | |||
var __awaiter = (this && this.__awaiter) || function(thisArg, _arguments, P, generator) { | |||
function adopt(value) { | |||
return value instanceof P ? value : new P(function(resolve) { | |||
resolve(value); | |||
}); | |||
} | |||
return new(P || (P = Promise))(function(resolve, reject) { | |||
function fulfilled(value) { | |||
try { | |||
step(generator.next(value)); | |||
} catch (e) { | |||
reject(e); | |||
} | |||
} | |||
function rejected(value) { | |||
try { | |||
step(generator["throw"](value)); | |||
} catch (e) { | |||
reject(e); | |||
} | |||
} | |||
function step(result) { | |||
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); | |||
} | |||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |||
}); | |||
}; | |||
Object.defineProperty(exports, "__esModule", { | |||
value: true | |||
}); | |||
var zaudioCbName; | |||
(function(zaudioCbName) { | |||
zaudioCbName["onWaiting"] = "waiting"; | |||
zaudioCbName["onError"] = "error"; | |||
zaudioCbName["onTimeUpdate"] = "playing"; | |||
zaudioCbName["onCanplay"] = "canPlay"; | |||
zaudioCbName["onPause"] = "pause"; | |||
zaudioCbName["onEnded"] = "ended"; | |||
zaudioCbName["setAudio"] = "setAudio"; | |||
zaudioCbName["updateAudio"] = "updateAudio"; | |||
zaudioCbName["seek"] = "seek"; | |||
zaudioCbName["onStop"] = "stop"; | |||
zaudioCbName["syncStateOn"] = "syncStateOn"; | |||
})(zaudioCbName || (zaudioCbName = {})); | |||
let zaudioCbNameArr = []; | |||
for (const key in zaudioCbName) { | |||
if (Object.prototype.hasOwnProperty.call(zaudioCbName, key)) { | |||
const item = zaudioCbName[key]; | |||
zaudioCbNameArr.push(item); | |||
} | |||
} | |||
const util_1 = require("./util"); | |||
/** | |||
* ZAudio类 | |||
* @class ZAudio | |||
* @constructor | |||
* @param {String} defaultCover 音频默认封面 | |||
* @param {Boolean} continuePlay 继续播放,错误播放或结束播放后执行 | |||
* @param {Boolean} autoPlay 自动播放,部分浏览器不支持 | |||
* @property {Number} renderIndex 当前渲染索引 | |||
* @property {<audioinfo>} renderinfo 当前渲染数据 | |||
* @property {Array<audio>} audiolist 音频列表数组 | |||
* @property {<audioinfo>} playinfo 当前播放数据 | |||
* @property {Boolean} paused 音频暂停状态 | |||
* @property {Number} playIndex 当前播放索引 | |||
* @property {Boolean} renderIsPlay 渲染与播放是否一致 | |||
* | |||
* @method on(event, action, fn) 回调函数注册业务事件 | |||
* @method off(event, action) 回调函数中卸载业务事件 | |||
* @method setRender(data) 指定音频, 渲染到zaudio组件 | |||
* @method syncRender() 同步并渲染当前的播放状态 | |||
* @method operate(index) 播放或暂停指定索引的音频 | |||
* @method setAudio(list) 覆盖音频列表 | |||
* @method updateAudio(list) 添加音频列表 | |||
* @method stop() 强制暂停当前播放音频 | |||
* @method stepPlay(count) 快进快退 | |||
* @method syncStateOn(action, cb) 注册一个用于同步获取当前播放状态的事件 | |||
* @method syncStateOff(action) 卸载用于同步获取当前播放状态的事件 | |||
* | |||
* | |||
* **/ | |||
class ZAudio extends util_1.EventBus { | |||
constructor(options) { | |||
super(); | |||
this.loading = false; | |||
this.renderIndex = 0; | |||
this.audiolist = []; | |||
this.renderinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
this.playinfo = { | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
current_value: 0, | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}; | |||
this.paused = true; | |||
this.uPause = false; | |||
this.autoPlay = false; | |||
this.defaultCover = ""; | |||
this.continuePlay = true; | |||
//fix: 防抖触发音频播放中事件 | |||
this.throttlePlaying = util_1.throttle(() => { | |||
this.emit(zaudioCbName.onTimeUpdate, this.playinfo); | |||
this.syncStateEmit(); | |||
}, 1000); | |||
let { | |||
defaultCover, | |||
autoPlay, | |||
continuePlay | |||
} = options; | |||
this.defaultCover = defaultCover; | |||
this.autoPlay = autoPlay; | |||
this.continuePlay = continuePlay; | |||
this.init(); | |||
} | |||
init() { | |||
// #ifndef H5 | |||
var audioCtx = uni.getBackgroundAudioManager(); | |||
// #endif | |||
// #ifdef H5 | |||
var audioCtx = uni.createInnerAudioContext(); | |||
audioCtx.autoplay = this.autoPlay; | |||
// #endif | |||
this.audioCtx = audioCtx; | |||
this.audioCtx.onWaiting(this.onWaitingHandler.bind(this)); | |||
this.audioCtx.onCanplay(this.onCanplayHandler.bind(this)); | |||
this.audioCtx.onPlay(this.onPlayHandler.bind(this)); | |||
this.audioCtx.onPause(this.onPauseHandler.bind(this)); | |||
this.audioCtx.onStop(this.onStopHandler.bind(this)); | |||
this.audioCtx.onEnded(this.onEndedHandler.bind(this)); | |||
this.audioCtx.onTimeUpdate(this.onTimeUpdateHandler.bind(this)); | |||
this.audioCtx.onError(this.onErrorHandler.bind(this)); | |||
//fix: 修复iOS原生音频切换不起作用 | |||
// #ifdef APP-PLUS | |||
if (uni.getSystemInfoSync().platform == "ios") { | |||
const bgMusic = plus.audio.createPlayer(); | |||
bgMusic.addEventListener("prev", () => { | |||
this.changeplay(-1); | |||
}); | |||
bgMusic.addEventListener("next", () => { | |||
this.changeplay(1); | |||
}); | |||
} | |||
// #endif | |||
// #ifndef H5 | |||
setTimeout(() => { | |||
if (this.autoPlay) { | |||
this.operate(); | |||
} | |||
}, 500); | |||
// #endif | |||
this.appCheckReplay(); | |||
} | |||
//检测on off的参数 | |||
checkEventParams(event, action, fn) { | |||
if (zaudioCbNameArr.indexOf(event) < 0) { | |||
console.error(`参数${event}错误, 必须为${zaudioCbNameArr.join(" | ")}中某一项`); | |||
return false; | |||
} | |||
if (typeof action !== "string" && typeof action !== "symbol") { | |||
console.error(`参数${action}错误, 参数必须为string或symbol类型`); | |||
return false; | |||
} | |||
if (fn && typeof fn !== "function") { | |||
console.error("fn参数错误"); | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
* @description 回调中卸载业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @returns undefined | |||
* **/ | |||
off(event, action) { | |||
if (!this.checkEventParams(event, action)) | |||
return; | |||
super.off(event, action); | |||
} | |||
/** | |||
* @description 回调中注册业务事件 | |||
* @param {<zaudioCbName>} event 回调名称枚举值 | |||
* @param {Sting|Symbol} action 业务函数名,用于区分不同业务 | |||
* @param {function(object|string|number|undefined):undefined} fn 业务函数, 参数或为音频状态 | |||
* @returns undefined | |||
* **/ | |||
on(event, action, fn) { | |||
if (!this.checkEventParams(event, action)) | |||
return; | |||
super.on(event, action, fn); | |||
} | |||
/** | |||
* @description 订阅触发音频回调 | |||
* @param {<zaudioCbName>} event 回调名称枚举值,具体看zaudioCbName | |||
* @param {object|string|number|undefined} data 订阅触发回调时,传的音频属性 | |||
* @returns undefined | |||
* **/ | |||
emit(event, data) { | |||
super.emit(event, data); | |||
} | |||
commit(action, data) { | |||
typeof this[action] === "function" && this[action](data); | |||
} | |||
onWaitingHandler() { | |||
this.commit("setLoading", true); | |||
this.emit(zaudioCbName.onWaiting, true); | |||
this.syncStateEmit(); | |||
} | |||
onCanplayHandler() { | |||
this.emit(zaudioCbName.onCanplay, this.playinfo); | |||
this.commit("setLoading", false); | |||
this.syncStateEmit(); | |||
} | |||
onPlayHandler() { | |||
// #ifdef APP-PLUS | |||
this.commit("setPlayinfo", { | |||
duration: util_1.formatSeconds(this.audioCtx.duration), | |||
duration_value: this.audioCtx.duration, | |||
}); | |||
// #endif | |||
this.commit("setPause", false); | |||
this.commit("setUnnormalPause", false); | |||
} | |||
onPauseHandler() { | |||
this.commit("setPause", true); | |||
this.emit(zaudioCbName.onPause); | |||
this.syncStateEmit(); | |||
} | |||
onStopHandler() { | |||
this.commit("setPause", true); | |||
this.emit(zaudioCbName.onStop); | |||
this.syncStateEmit(); | |||
} | |||
onEndedHandler() { | |||
this.commit("setPause", true); | |||
this.audioCtx.startTime = 0; | |||
this.commit("setPlayinfo", { | |||
current: "00:00:00", | |||
current_value: 0, | |||
src: "", | |||
}); | |||
this.emit(zaudioCbName.onEnded); | |||
this.syncStateEmit(); | |||
//续播 | |||
if (this.continuePlay) { | |||
this.changeplay(1); | |||
} else { | |||
let nextkey = this.getNextKey(1); | |||
this.commit("setRender", nextkey); | |||
} | |||
} | |||
onTimeUpdateHandler() { | |||
if (this.renderIsPlay) { | |||
//fix: 解决播放进度大于总进度问题 | |||
let currentTime = this.audioCtx.currentTime | |||
// let currentTime = this.audioCtx.currentTime > this.audioCtx.duration ? | |||
// this.audioCtx.duration : | |||
// this.audioCtx.currentTime; | |||
this.commit("setPlayinfo", { | |||
current: util_1.formatSeconds(currentTime), | |||
current_value: currentTime, | |||
}); | |||
// #ifndef APP-PLUS | |||
//fix: 解决小程序与h5无法获取总进度的问题 | |||
if (this.audioCtx.duration != this.playinfo.duration_value) { | |||
this.commit("setPlayinfo", { | |||
duration: util_1.formatSeconds(this.audioCtx.duration), | |||
duration_value: this.audioCtx.duration, | |||
}); | |||
} | |||
// #endif | |||
} | |||
this.throttlePlaying(); | |||
} | |||
onErrorHandler() { | |||
this.commit("setPause", true); | |||
this.commit("setRender", { | |||
src: "", | |||
title: "", | |||
singer: "", | |||
coverImgUrl: "", | |||
}); | |||
this.commit("setPlayinfo", { | |||
current: "00:00:00", | |||
current_value: 0, | |||
duration: "00:00:00", | |||
duration_value: 0, | |||
title: "", | |||
src: "", | |||
}); | |||
this.emit(zaudioCbName.onError); | |||
this.syncStateEmit(); | |||
if (this.continuePlay) { | |||
this.changeplay(1); | |||
} | |||
} | |||
/** | |||
* @description 实时渲染当前状态 | |||
* @returns undefined | |||
* **/ | |||
syncRender() { | |||
this.setRender(this.playIndex); | |||
} | |||
/** | |||
* @description 注册一个实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @param {Funtion} fn 实时获取ZAudio属性回调 | |||
* @returns undefined | |||
* **/ | |||
syncStateOn(action, fn) { | |||
typeof fn === "function" && this.on(zaudioCbName.syncStateOn, action, fn); | |||
} | |||
/** | |||
* @description 卸载实时获取ZAudio属性的方法 | |||
* @param {String} action 自定义业务名 | |||
* @returns undefined | |||
* **/ | |||
syncStateOff(action) { | |||
this.off(zaudioCbName.syncStateOn, action); | |||
} | |||
/** | |||
* @description 订阅实时获取ZAudio属性的方法 | |||
* @returns undefined | |||
* **/ | |||
syncStateEmit() { | |||
this.emit(zaudioCbName.syncStateOn, { | |||
renderIndex: this.renderIndex, | |||
audiolist: this.audiolist, | |||
renderinfo: this.renderinfo, | |||
playinfo: this.playinfo, | |||
paused: this.paused, | |||
playIndex: this.playIndex, | |||
renderIsPlay: this.renderIsPlay, | |||
loading: this.loading, | |||
}); | |||
} | |||
/** | |||
* @description 跳转播放 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
seek(value) { | |||
let val = value > this.audioCtx.duration ? this.audioCtx.duration : value; | |||
this.audioCtx.seek(val); | |||
this.commit("setPlayinfo", { | |||
current: util_1.formatSeconds(val), | |||
current_value: val, | |||
}); | |||
// setTimeout(() => { | |||
// this.emit(zaudioCbName.seek, this.playinfo.current); | |||
// }, 0); | |||
this.emit(zaudioCbName.seek, this.playinfo.current); | |||
} | |||
/** | |||
* @description 快进 | |||
* @param {Number} value 跳转位置 | |||
* @returns undefined | |||
* **/ | |||
stepPlay(value) { | |||
if (this.renderIsPlay) { | |||
let pos = this.playinfo.current_value + value; | |||
this.seek(pos); | |||
} | |||
} | |||
/** | |||
* @description 获取下一首歌曲索引(用于渲染和播放) | |||
* @param {Number} count 切换数量 | |||
* @returns number | |||
* **/ | |||
getNextKey(count) { | |||
let nextkey = this.renderIndex; | |||
nextkey += count; | |||
nextkey = | |||
nextkey < 0 ? | |||
this.audiolist.length - 1 : | |||
nextkey > this.audiolist.length - 1 ? | |||
0 : | |||
nextkey; | |||
return nextkey; | |||
} | |||
/** | |||
* @description 切歌 | |||
* @param {Number} count 数量 | |||
* @returns undefined | |||
* **/ | |||
changeplay(count) { | |||
let nextkey = this.getNextKey(count); | |||
this.commit("setPause", true); | |||
this.operate(nextkey); | |||
} | |||
/** | |||
* @description 手动播放或暂停, 并渲染对应的数据 | |||
* @param {Number|String|<audioInfo>|undefined} key 索引或音频对象 | |||
* @returns undefined | |||
* **/ | |||
operate(key) { | |||
key !== undefined && this.commit("setRender", key); | |||
this.operation(); | |||
} | |||
/** | |||
* @description 强制暂停播放 | |||
* @returns undefined | |||
* **/ | |||
stop() { | |||
this.audioCtx.pause(); | |||
this.commit("setPause", true); | |||
this.commit("setUnnormalPause", true); | |||
this.emit(zaudioCbName.onStop); | |||
} | |||
//播放,暂停事件判断, | |||
//播放数据与渲染数据相同时: 播放->暂停, 暂停->播放 | |||
//播放数据与渲染数据不相同时: 播放渲染音频 | |||
operation() { | |||
return __awaiter(this, void 0, void 0, function*() { | |||
const { | |||
duration, | |||
current, | |||
duration_value, | |||
current_value, | |||
src, | |||
} = this.playinfo; | |||
const { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
} = this.renderinfo; | |||
let renderIsPlay = this.renderIsPlay; | |||
let paused = this.paused; | |||
if (!renderIsPlay) { | |||
//渲染与播放地址 不同 | |||
this.audioCtx.src = renderSrc; | |||
this.audioCtx.title = renderTitle; | |||
this.audioCtx.singer = renderSinger; | |||
this.audioCtx.coverImgUrl = renderCoverImgUrl || this.defaultCover; | |||
this.audioCtx.startTime = 0; | |||
this.audioCtx.seek(0); | |||
this.audioCtx.play(); | |||
this.commit("setPause", false); | |||
this.commit("setPlayinfo", { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
}); | |||
} else { | |||
if (paused) { | |||
//渲染与播放地址相同 | |||
this.audioCtx.play(); | |||
this.audioCtx.startTime = current_value; | |||
// this.audioCtx.seek(current_value); | |||
this.commit("setPause", false); | |||
this.commit("setPlayinfo", { | |||
src: renderSrc, | |||
title: renderTitle, | |||
singer: renderSinger, | |||
coverImgUrl: renderCoverImgUrl, | |||
}); | |||
} else { | |||
this.audioCtx.pause(); | |||
this.commit("setPause", true); | |||
this.commit("setUnnormalPause", true); | |||
} | |||
} | |||
}); | |||
} | |||
/** | |||
* @description 覆盖音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
setAudio(data) { | |||
this.audiolist = [...data]; | |||
this.emit(zaudioCbName.setAudio, this.audiolist); | |||
this.syncStateEmit(); | |||
} | |||
/** | |||
* @description 添加音频 | |||
* @param {Array<audio>} data 音频数组 | |||
* @returns undefined | |||
* **/ | |||
updateAudio(data) { | |||
this.audiolist.push(...data); | |||
this.emit(zaudioCbName.updateAudio, this.audiolist); | |||
this.syncStateEmit(); | |||
} | |||
/** | |||
* @description 设置当前播放信息 | |||
* @param {<audioInfo>} data 音频对象 | |||
* @returns undefined | |||
* **/ | |||
setPlayinfo(data) { | |||
for (let i in data) { | |||
this.playinfo[i] = data[i]; | |||
} | |||
} | |||
/** | |||
* @description 设置暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setPause(data) { | |||
this.paused = data; | |||
} | |||
/** | |||
* @description 设置loading | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setLoading(data) { | |||
this.loading = data; | |||
} | |||
/** | |||
* @description 设置通话时暂停状态 | |||
* @param {boolean} data 布尔值 | |||
* @returns undefined | |||
* **/ | |||
setUnnormalPause(data) { | |||
this.uPause = data; | |||
} | |||
/** | |||
* @description 设置渲染 | |||
* @param {number | string | audioInfo} data 索引或渲染信息 | |||
* @returns undefined | |||
* **/ | |||
setRender(data) { | |||
if (this.audiolist.length == 0) | |||
return; | |||
if (typeof data === "number" || typeof data === "string") { | |||
this.renderIndex = typeof data === "string" ? parseInt(data) : data; | |||
this.renderinfo = { | |||
src: this.audiolist[this.renderIndex].src, | |||
title: this.audiolist[this.renderIndex].title, | |||
singer: this.audiolist[this.renderIndex].singer, | |||
coverImgUrl: this.audiolist[this.renderIndex].coverImgUrl, | |||
current: "00:00:00", | |||
duration: "00:00:00", | |||
current_value: 0, | |||
duration_value: 100, | |||
}; | |||
} else { | |||
this.renderinfo = data; | |||
let renderIndex = this.audiolist.findIndex((i) => i.src == data.src); | |||
if (renderIndex >= 0) { | |||
this.renderIndex = renderIndex; | |||
} | |||
} | |||
this.syncStateEmit(); | |||
} | |||
//当前索引 | |||
get playIndex() { | |||
let index = this.audiolist.findIndex((i) => i.src == this.playinfo.src); | |||
return index <= 0 ? 0 : index; | |||
} | |||
//渲染与播放是否一致 | |||
get renderIsPlay() { | |||
return this.renderinfo.src == this.playinfo.src; | |||
} | |||
//app端判断电话来电后, 音频意外中断之后的继续播放 | |||
appCheckReplay() { | |||
let _t = this; | |||
// #ifdef APP-PLUS | |||
try { | |||
if (uni.getSystemInfoSync().platform == "android") { | |||
var main = plus.android.runtimeMainActivity(); | |||
var Context = plus.android.importClass("android.content.Context"); | |||
var telephonyManager = plus.android.importClass("android.telephony.TelephonyManager"); | |||
var telephonyManager = plus.android | |||
.runtimeMainActivity() | |||
.getSystemService(Context.TELEPHONY_SERVICE); | |||
var receiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", { | |||
onReceive: function(intent) { | |||
//实现onReceiver回调函数 | |||
plus.android.importClass(intent); | |||
var telephonyManager = plus.android.importClass( | |||
"android.telephony.TelephonyManager"); | |||
var telephonyManager = plus.android | |||
.runtimeMainActivity() | |||
.getSystemService(Context.TELEPHONY_SERVICE); | |||
var phonetype = telephonyManager.getCallState(); | |||
var phoneNumber = intent.getStringExtra(telephonyManager | |||
.EXTRA_INCOMING_NUMBER); | |||
if (phonetype == 0 && !_t.uPause) { | |||
_t.audioCtx.play(); | |||
} | |||
}, | |||
}); | |||
var IntentFilter = plus.android.importClass("android.content.IntentFilter"); | |||
var filter = new IntentFilter(); | |||
filter.addAction(telephonyManager.ACTION_PHONE_STATE_CHANGED); //监听开关 | |||
main.registerReceiver(receiver, filter); //注册监听 | |||
} else if (uni.getSystemInfoSync().platform == "ios") { | |||
var callstatus = false; | |||
var CTCall = plus.ios.importClass("CTCall"); | |||
var CTCallCenter = plus.ios.importClass("CTCallCenter"); | |||
var center = new CTCallCenter(); | |||
center.init(); | |||
center.setCallEventr(function(ctCall) { | |||
callstatus = !callstatus; | |||
if (!callstatus && !_t.uPause) { | |||
_t.audioCtx.play(); | |||
} else { | |||
_t.audioCtx.pause(); | |||
} | |||
}); | |||
} | |||
} catch (err) { | |||
console.warn(err); | |||
} | |||
// #endif | |||
} | |||
} | |||
exports.default = ZAudio; | |||
ZAudio.version = "2.2.51"; |
@@ -0,0 +1,2 @@ | |||
import ZAudio from "./dist/zaudio.js"; | |||
export default ZAudio |
@@ -0,0 +1,356 @@ | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audio.theme1 { | |||
padding: 0 30upx 30upx; | |||
background: #fff; | |||
.top { | |||
& > view:nth-child(2) { | |||
.title { | |||
font-weight: bold; | |||
font-size: 34rpx; | |||
margin-top: 50rpx; | |||
text-align: center; | |||
} | |||
.singer { | |||
color: #999; | |||
font-size: 26rpx; | |||
margin-top: 10rpx; | |||
text-align: center; | |||
margin-bottom: 18rpx; | |||
} | |||
} | |||
} | |||
.audio-wrapper { | |||
display: flex; | |||
align-items: center; | |||
width: 90%; | |||
margin: 0 auto; | |||
} | |||
.audio-button-box { | |||
display: flex; | |||
align-items: center; | |||
margin: 40rpx auto 0; | |||
justify-content: space-around; | |||
height: 100rpx | |||
} | |||
.audio-number { | |||
font-size: 24upx; | |||
line-height: 1; | |||
color: #333; | |||
} | |||
.audio-slider { | |||
flex: 1; | |||
margin: 0 30rpx 0 35rpx; | |||
} | |||
.audio-control-wrapper { | |||
margin: 20rpx auto; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
position: relative; | |||
} | |||
.cover { | |||
width: 350rpx; | |||
height: 350rpx; | |||
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); | |||
border-radius: 5px; | |||
} | |||
.playbox{ | |||
width: 100rpx; | |||
height: 100rpx; | |||
display:flex; | |||
align-items: center; | |||
justify-content: center; | |||
} | |||
.play, | |||
.pause { | |||
width: 100rpx; | |||
height: 100rpx; | |||
&.loading{ | |||
width: 80rpx; | |||
height: 80rpx; | |||
animation: rotating 2s linear infinite; | |||
} | |||
} | |||
.prevbtn, | |||
.nextbtn { | |||
width: 40rpx; | |||
height: 40rpx; | |||
} | |||
.prevplay { | |||
width: 40rpx; | |||
height: 40rpx; | |||
transform: rotateZ(180deg); | |||
} | |||
.nextplay { | |||
width: 40rpx; | |||
height: 40rpx; | |||
} | |||
} | |||
.imt-audio.theme2 { | |||
background: #fff; | |||
border: 1px solid #cecece; | |||
width: 100%; | |||
margin: 0 auto; | |||
overflow: hidden; | |||
.top { | |||
background: #fff; | |||
display: flex; | |||
align-items: center; | |||
height: 150rpx; | |||
& > view:nth-child(2) { | |||
flex: 1; | |||
margin: 0 30rpx; | |||
.title { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
margin-top: 24rpx; | |||
text{ | |||
font-size: 30rpx; | |||
text-align: left; | |||
max-width: 100%; | |||
@include textoverflow; | |||
flex: 1; | |||
} | |||
.audio-number { | |||
font-size: 24upx; | |||
line-height: 1; | |||
color: #333; | |||
} | |||
} | |||
.singer { | |||
color: #999; | |||
font-size: 26rpx; | |||
margin-top: 10rpx; | |||
text-align: left; | |||
margin-bottom: 18rpx; | |||
max-width: 100%; | |||
@include textoverflow; | |||
} | |||
} | |||
} | |||
.cover { | |||
width: 120rpx; | |||
height: 120rpx; | |||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
border-radius: 50%; | |||
border: 2px solid #fff; | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.cover.on { | |||
-webkit-animation: 10s rowup linear infinite normal; | |||
animation: 10s rowup linear infinite normal; | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.audio-control-wrapper{ | |||
width: 150rpx; | |||
height: 150rpx; | |||
display: flex; | |||
align-items:center; | |||
justify-content: center; | |||
background: #efefef; | |||
background-size: contain; | |||
background-position: center; | |||
background-repeat: no-repeat; | |||
} | |||
.play { | |||
width: 80rpx; | |||
height: 80rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
&.loading{ | |||
width: 60rpx; | |||
height: 60rpx; | |||
animation: rotating 2s linear infinite; | |||
} | |||
} | |||
.prevbtn { | |||
width: 48rpx; | |||
height: 48rpx; | |||
margin-right: 40rpx; | |||
} | |||
.nextbtn { | |||
width: 48rpx; | |||
height: 48rpx; | |||
margin-left: 40rpx; | |||
} | |||
} | |||
.imt-audio.theme3 { | |||
background: #ccc; | |||
width: 100%; | |||
overflow: hidden; | |||
display: flex; | |||
padding: 40rpx 20rpx; | |||
box-sizing: border-box; | |||
max-height: 200rpx; | |||
position:relative; | |||
.top { | |||
width: 140rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
position: relative; | |||
} | |||
.audio-wrapper { | |||
display: flex; | |||
flex-direction: column; | |||
flex: 1; | |||
color: #fff; | |||
margin-left: 20rpx; | |||
.titlebox { | |||
display: flex; | |||
line-height: 46rpx; | |||
margin-bottom: 30rpx; | |||
.title { | |||
font-size: 30rpx; | |||
max-width: 50%; | |||
@include textoverflow; | |||
} | |||
.singer { | |||
margin-left: 20rpx; | |||
font-size: 28rpx; | |||
max-width: 50%; | |||
@include textoverflow; | |||
} | |||
} | |||
} | |||
.slidebox { | |||
display: flex; | |||
justify-content: space-between; | |||
width: 96%; | |||
view{ | |||
&:first-child{ | |||
font-size: 28rpx; | |||
} | |||
&:last-child{ | |||
font-size: 28rpx; | |||
text{ | |||
&:last-child{ | |||
margin-left: 40rpx; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 4px; | |||
} | |||
.audio-slider { | |||
position: absolute; | |||
top: 0; | |||
margin: 0; | |||
width: 100%; | |||
left: 0; | |||
padding: 0; | |||
} | |||
.cover { | |||
width: 120rpx; | |||
height: 120rpx; | |||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
animation-fill-mode: forwards; | |||
-webkit-animation-fill-mode: forwards; | |||
} | |||
.play { | |||
width: 80rpx; | |||
height: 80rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading{ | |||
width: 60rpx; | |||
height: 60rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} |
@@ -0,0 +1,416 @@ | |||
<template> | |||
<view class="imt-audio" :class="[`${theme}`]" v-if="audiolist.length > 0"> | |||
<template v-if="theme == 'theme4'"> | |||
<view class="imt-audios"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="audio-flex"> | |||
<text> | |||
{{renderData('current')}} | |||
</text> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="16" | |||
:value="renderData('current_value')" :max="renderData('duration_value')" @change="change" | |||
:disabled="!renderIsPlay"></slider> | |||
<text v-if="!duration"> | |||
{{renderData('duration')}} | |||
</text> | |||
<text v-else>{{ duration }}</text> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme3'"> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="0" :value="renderData('current_value')" | |||
:max="renderData('duration_value')" @change="change" :disabled="!renderIsPlay"></slider> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover" | |||
:class="{ on: !renderData('paused') }"></image> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="titlebox"> | |||
<view class="title">{{ renderData('title') }}</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
<view class="slidebox"> | |||
<view>{{ renderData('current') }}/ {{ renderData('duration') }}</view> | |||
<view> | |||
<text @click="changeplay(-1)">上一首</text> | |||
<text @click="changeplay(1)">下一首</text> | |||
</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme2'"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper" :style="{backgroundImage: `url(${renderData('coverImgUrl')})`}"> | |||
<image :src="require('./static/loading.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<image :src="require('./static/playbtn.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<image :src="require('./static/pausebtn.png')" alt="" @click="operate" class="play" v-else> | |||
</image> | |||
</template> | |||
</view> | |||
<view> | |||
<view class="title"> | |||
<text>{{ renderData('title') }}</text> | |||
<view class="audio-number">{{ renderData('current') }}/{{ renderData('duration') }}</view> | |||
</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
</view> | |||
</template> | |||
<template v-if="theme == 'theme1'"> | |||
<view class="top"> | |||
<view class="audio-control-wrapper"> | |||
<image :src="renderData('coverImgUrl')" mode="aspectFill" class="cover" | |||
:class="{ on: !renderData('paused') }"></image> | |||
</view> | |||
<view> | |||
<view class="title">{{ renderData('title') }}</view> | |||
<view class="singer">{{ renderData('singer') }}</view> | |||
</view> | |||
</view> | |||
<view class="audio-wrapper"> | |||
<view class="audio-number">{{ renderData('current') }}</view> | |||
<slider class="audio-slider" :activeColor="themeColor" block-size="16" | |||
:value="renderData('current_value')" :max="renderData('duration_value')" @change="change" | |||
:disabled="!renderIsPlay"></slider> | |||
<view class="audio-number">{{ renderData('duration') }}</view> | |||
</view> | |||
<view class="audio-button-box"> | |||
<!-- 块退15s --> | |||
<image :src="require('./static/prev.png')" class="prevbtn" @click="stepPlay(-15)" mode="widthFix"> | |||
</image> | |||
<!-- 上一首 --> | |||
<image :src="require('./static/go.png')" class="prevplay" @click="changeplay(-1)" mode="widthFix"> | |||
</image> | |||
<div class="playbox"> | |||
<image :src="require('./static/loading2.png')" v-if="loading" class="play loading"></image> | |||
<template v-else> | |||
<!-- 播放 --> | |||
<image :src="require('./static/playbtn2.png')" alt="" @click="operate" class="play" | |||
v-if="renderData('paused')"></image> | |||
<!-- 暂停 --> | |||
<image :src="require('./static/pausebtn2.png')" alt="" @click="operate" class="pause" v-else> | |||
</image> | |||
</template> | |||
</div> | |||
<!-- 下一首 --> | |||
<image :src="require('./static/go.png')" class="nextplay" @click="changeplay(1)" mode="widthFix"> | |||
</image> | |||
<!-- 快进15s --> | |||
<image :src="require('./static/next.png')" class="nextbtn" @click="stepPlay(15)" mode="widthFix"> | |||
</image> | |||
</view> | |||
</template> | |||
</view> | |||
</template> | |||
<script> | |||
export default { | |||
props: { | |||
theme: { | |||
type: String, // 主题 'theme1' or 'theme2' | |||
default: 'theme1' | |||
}, | |||
themeColor: { | |||
type: String, | |||
default: '#42b983' | |||
}, | |||
duration: { | |||
type: String, | |||
default: "" | |||
} | |||
}, | |||
data() { | |||
return { | |||
playinfo: this.$zaudio.playinfo, | |||
audiolist: this.$zaudio.audiolist, | |||
paused: this.$zaudio.paused, | |||
renderIsPlay: this.$zaudio.renderIsPlay, | |||
audio: this.$zaudio.renderinfo, | |||
loading: this.$zaudio.loading, | |||
action: Symbol('zaudio') | |||
}; | |||
}, | |||
computed: { | |||
renderData() { | |||
return name => { | |||
if (!this.renderIsPlay) { | |||
if (name == 'paused') { | |||
return true; | |||
} | |||
return this.audio[name]; | |||
} else { | |||
if (name == 'paused') { | |||
return this.paused; | |||
} | |||
return this.playinfo[name]; | |||
} | |||
}; | |||
} | |||
}, | |||
mounted() { | |||
this.$nextTick(() => { | |||
let action = this.action; | |||
this.$zaudio.syncStateOn(action, ({ | |||
audiolist, | |||
paused, | |||
playinfo, | |||
renderIsPlay, | |||
renderinfo, | |||
loading, | |||
}) => { | |||
this.audiolist = audiolist; | |||
this.paused = paused; | |||
this.playinfo = playinfo; | |||
this.renderIsPlay = renderIsPlay; | |||
this.audio = renderinfo; | |||
this.loading = loading; | |||
}); | |||
this.$zaudio.syncRender() | |||
}); | |||
}, | |||
methods: { | |||
// 转换时间 | |||
formatSeconds(seconds) { | |||
var result = typeof seconds === "string" ? parseFloat(seconds) : seconds; | |||
if (isNaN(result)) return ""; | |||
let h = Math.floor(result / 3600) < 10 ? | |||
"0" + Math.floor(result / 3600) : | |||
Math.floor(result / 3600); | |||
let m = Math.floor((result / 60) % 60) < 10 ? | |||
"0" + Math.floor((result / 60) % 60) : | |||
Math.floor((result / 60) % 60) + h * 60; | |||
let s = Math.floor(result % 60) < 10 ? | |||
"0" + Math.floor(result % 60) : | |||
Math.floor(result % 60); | |||
return `${h}:${m}:${s}`; | |||
}, | |||
//播放or暂停 | |||
operate() { | |||
this.$zaudio.operate(); | |||
}, | |||
//进度拖到 | |||
change(event) { | |||
if (this.renderIsPlay) { | |||
console.log('组件内', event) | |||
this.$zaudio.seek(Math.floor(event.detail.value)); | |||
} | |||
}, | |||
//快进 | |||
stepPlay(value) { | |||
this.$zaudio.stepPlay(value); | |||
}, | |||
//切歌 | |||
changeplay(count) { | |||
this.$zaudio.changeplay(count); | |||
} | |||
}, | |||
beforeDestroy() { | |||
this.$zaudio.playinfo.duration = '00:00:00' | |||
this.$zaudio.playinfo.duration_value = '00:00:00' | |||
//组件卸载时卸载业务逻辑 | |||
let action = this.action; | |||
this.$zaudio.syncStateOff(action) | |||
this.$zaudio.stop() | |||
} | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
@import './index.scss'; | |||
// #ifdef MP-WEIXIN | |||
.theme3 .audio-slider { | |||
margin-top: -8px !important; | |||
} | |||
// #endif | |||
@mixin textoverflow() { | |||
display: -webkit-box; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
-webkit-box-orient: vertical; | |||
-webkit-line-clamp: 1; | |||
} | |||
@keyframes rowup { | |||
0% { | |||
-webkit-transform: translate(-50%, -50%) rotate(0deg); | |||
transform-origin: center center; | |||
} | |||
100% { | |||
-webkit-transform: translate(-50%, -50%) rotate(360deg); | |||
transform-origin: center center; | |||
} | |||
} | |||
.imt-audios { | |||
position: relative; | |||
width: 100%; | |||
height: 81rpx; | |||
display: flex; | |||
box-sizing: border-box; | |||
background: #fff; | |||
.top { | |||
position: relative; | |||
width: 100rpx; | |||
} | |||
.audio-wrapper { | |||
position: relative; | |||
padding: 0 20rpx; | |||
display: flex; | |||
flex: 1; | |||
color: #fff; | |||
.popup { | |||
position: absolute; | |||
right: 32rpx; | |||
top: -122rpx; | |||
z-index: 100; | |||
width: 136rpx; | |||
height: 122rpx; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
flex-direction: column; | |||
background: #fff; | |||
border: 1rpx solid #E0E0E0; | |||
transition: all 0.25s linear; | |||
opacity: 0; | |||
image { | |||
width: 32rpx; | |||
height: 32rpx; | |||
} | |||
text { | |||
margin-top: 10rpx; | |||
color: #333; | |||
font-size: 24rpx; | |||
} | |||
.act-test { | |||
color: #2671E2; | |||
} | |||
} | |||
.close { | |||
opacity: 1; | |||
} | |||
} | |||
.slidebox { | |||
flex-shrink: 0; | |||
display: flex; | |||
align-items: center; | |||
.slide-img { | |||
width: 32rpx; | |||
height: 8rpx; | |||
} | |||
} | |||
/deep/ .uni-slider-tap-area { | |||
padding: 0; | |||
} | |||
/deep/ .uni-slider-wrapper { | |||
min-height: 0; | |||
} | |||
/deep/ .uni-slider-handle-wrapper { | |||
height: 6px; | |||
} | |||
.audio-slider { | |||
flex-grow: 1; | |||
} | |||
.play { | |||
width: 48rpx; | |||
height: 48rpx; | |||
z-index: 99; | |||
background: rgba(0, 0, 0, 0.4); | |||
border-radius: 50%; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
transform: translate(-50%, -50%); | |||
&.loading { | |||
width: 48rpx; | |||
height: 48rpx; | |||
animation: rotating_theme3 2s linear infinite; | |||
} | |||
} | |||
} | |||
.audio-flex { | |||
padding: 0 32rpx 0 0; | |||
flex-grow: 1; | |||
display: flex; | |||
align-items: center; | |||
text { | |||
color: #70798D; | |||
} | |||
} | |||
@keyframes rotating { | |||
0% { | |||
transform: rotateZ(0deg) | |||
} | |||
100% { | |||
transform: rotateZ(360deg) | |||
} | |||
} | |||
@keyframes rotating_theme3 { | |||
0% { | |||
transform: translate(-50%, -50%) rotateZ(0deg) | |||
} | |||
100% { | |||
transform: translate(-50%, -50%) rotateZ(360deg) | |||
} | |||
} | |||
</style> |
@@ -2,10 +2,20 @@ import Vue from 'vue'; | |||
import App from './App'; | |||
import dayjs from './utils/dayjs.min.js' | |||
import store from './store/index.js' | |||
import ZAudio from '@/components/uniapp-zaudio/index.js' | |||
Vue.config.productionTip = false; | |||
let zaudio = new ZAudio({ | |||
continuePlay: false, //续播 | |||
autoPlay: false, // 自动播放 部分浏览器不支持 | |||
}) | |||
Vue.prototype.$zaudio = zaudio | |||
Vue.prototype.$dayjs = dayjs; | |||
// 引入全局uView | |||
import uView from 'uview-ui' | |||
Vue.use(uView); | |||
@@ -1,5 +1,5 @@ | |||
{ | |||
"name" : "去房智控管家", | |||
"name" : "数智工牌", | |||
"appid" : "__UNI__D88F14A", | |||
"description" : "AI营销助理", | |||
"versionName" : "1.1.0", | |||
@@ -91,7 +91,7 @@ | |||
}, | |||
"quickapp" : {}, | |||
"mp-weixin" : { | |||
"appid" : "wx8f883dca5ecc5510", | |||
"appid" : "wxe044603515ff2cb5", | |||
"setting" : { | |||
"urlCheck" : false, | |||
"es6" : true, | |||
@@ -2,45 +2,51 @@ | |||
<view class="translation"> | |||
<view style="display: flex;width: 100%;height: 100rpx;border-bottom: 1px solid #E0E0E0;"> | |||
<view style="width: 50%;display: flex;align-items: center;justify-content: center;font-size: 30rpx;"> | |||
<view style="line-height: 50rpx;" :class="roleindex == 0 ? 'bosdttom' : ''" @click="tapspagek(0)">画像语义词选择</view> | |||
<view style="line-height: 50rpx;" :class="roleindex == 0 ? 'bosdttom' : ''" @click="tapspagek(0)"> | |||
画像语义词选择</view> | |||
</view> | |||
<view style="width: 50%;display: flex;align-items: center;justify-content: center;font-size: 30rpx;"> | |||
<view style="line-height: 50rpx;" :class="roleindex == 1 ? 'bosdttom' : ''" @click="tapspagek(1)">关键词输入</view> | |||
<view style="line-height: 50rpx;" :class="roleindex == 1 ? 'bosdttom' : ''" @click="tapspagek(1)">关键词输入 | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if='roleindex==0' style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;"> | |||
<view v-if='roleindex==0' style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;"> | |||
<view style="display: flex;align-items: center;border-bottom: 1px solid #C9C9C9;height: 80rpx;"> | |||
<view>画像语义词:</view> | |||
<view style="width:70%" @click="oninputtap()"> | |||
<text v-if="Semanticword.length==0">请选择</text> | |||
<text v-else>{{Semanticword}}</text> | |||
</view> | |||
<view> | |||
<image src="https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/qf/more.png" style="width:12rpx;height:23rpx;margin-left: 16rpx;"> | |||
<view> | |||
<image src="https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/qf/more.png" | |||
style="width:12rpx;height:23rpx;margin-left: 16rpx;"> | |||
</view> | |||
</view> | |||
</view> | |||
<view v-if='roleindex==1' style="width: 690rpx;height: 64rpx;margin: 0 auto;margin-top: 30rpx;background: #F2F2F2;border-radius: 32rpx; | |||
display: flex;align-items: center;"> | |||
<view style="width: 10%;height: 64rpx;display: flex;align-items: center;"> | |||
<image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode=""></image> | |||
<image style="width: 28rpx;height: 28rpx;margin-left: 30rpx;" src="/static/images/search.png" mode=""> | |||
</image> | |||
</view> | |||
<view style="width: 90%;height: 64rpx;display: flex;align-items: center;"> | |||
<input type="text" @input="searchinfo" v-model="keyword" placeholder="请输入关键字" | |||
style="width: 100%;color: #999999;font-size: 24rpx;"/> | |||
<input type="text" @input="searchinfo" v-model="keyword" placeholder="请输入关键字" | |||
style="width: 100%;color: #999999;font-size: 24rpx;" /> | |||
</view> | |||
</view> | |||
<view style="width: 690rpx;margin: 0 auto;margin-top: 10rpx;"> | |||
<view style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view | |||
style="width: 100%;border-bottom: 1px solid #E0E0E0;display: flex;padding-bottom: 10rpx;margin-top: 40rpx;" | |||
v-for="(item,index) in listarr" :key='index' @click="toaidoinfo(item.Content,item.corpusId,item.index)"> | |||
<view style="width: 26rpx;height: 36rpx;margin-top: 4rpx;"> | |||
<image style="width: 26rpx;height: 28rpx;" src="/static/images/testimg.png" mode=""></image> | |||
</view> | |||
<view v-html="item.Content.text" style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view v-html="item.Content.text" | |||
style="color: #666666;font-size: 28rpx;line-height: 36rpx;margin-left: 10rpx;width: 80%;"></view> | |||
<view style="font-size: 28rpx;width: 10%;width: 14%;text-align: right;">{{item.Content.time}}</view> | |||
</view> | |||
</view> | |||
<u-select v-model="Showhiddenunits" mode="single-column" :list="selectlist" @confirm="confirm"></u-select> | |||
</view> | |||
@@ -52,15 +58,15 @@ | |||
export default { | |||
data() { | |||
return { | |||
customerId:'', | |||
listarr:[], | |||
keyword:'', | |||
skpl:'', | |||
roleindex:0, | |||
Showhiddenunits:false, | |||
selectlist:[], | |||
Semanticword:'', | |||
qujian:true | |||
customerId: '', | |||
listarr: [], | |||
keyword: '', | |||
skpl: '', | |||
roleindex: 0, | |||
Showhiddenunits: false, | |||
selectlist: [], | |||
Semanticword: '', | |||
qujian: true | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
@@ -68,47 +74,47 @@ | |||
this.statistical() | |||
}, | |||
methods: { | |||
statistical(){ | |||
statistical() { | |||
this.$u.get("/matchKeywords/findCARKeywords", { | |||
customerId: this.customerId | |||
}).then(res => { | |||
res.forEach((item,index)=>{ | |||
if(item.isInterval==0){ | |||
item.label=item.name+item.unit +'-'+ item.endName+item.unit; | |||
item.value=index | |||
}else{ | |||
item.label=item.name; | |||
item.value=index | |||
res.forEach((item, index) => { | |||
if (item.isInterval == 0) { | |||
item.label = item.name + item.unit + '-' + item.endName + item.unit; | |||
item.value = index | |||
} else { | |||
item.label = item.name; | |||
item.value = index | |||
} | |||
}) | |||
this.selectlist=res; | |||
this.selectlist = res; | |||
}) | |||
}, | |||
oninputtap(){ | |||
this.Showhiddenunits=true; | |||
oninputtap() { | |||
this.Showhiddenunits = true; | |||
}, | |||
confirm(e) { | |||
let indexs=e[0].value; | |||
this.selectlist.forEach((item,index)=>{ | |||
if(indexs==item.value){ | |||
this.Semanticword=item.name; | |||
this.keyword=item.matchName; | |||
if(item.isInterval==0){ | |||
this.qujian=false; | |||
this.Semanticword=item.name+item.unit+ '-'+ item.endName+item.unit; | |||
}else{ | |||
this.qujian=true; | |||
let indexs = e[0].value; | |||
this.selectlist.forEach((item, index) => { | |||
if (indexs == item.value) { | |||
this.Semanticword = item.name; | |||
this.keyword = item.matchName; | |||
if (item.isInterval == 0) { | |||
this.qujian = false; | |||
this.Semanticword = item.name + item.unit + '-' + item.endName + item.unit; | |||
} else { | |||
this.qujian = true; | |||
} | |||
} | |||
}) | |||
this.searchinfo() | |||
}, | |||
tapspagek(i){ | |||
this.roleindex=i; | |||
this.keyword=""; | |||
this.Semanticword=''; | |||
this.qujian=true; | |||
this.listarr=[]; | |||
tapspagek(i) { | |||
this.roleindex = i; | |||
this.keyword = ""; | |||
this.Semanticword = ''; | |||
this.qujian = true; | |||
this.listarr = []; | |||
}, | |||
formatTime(num) { | |||
//格式化时间格式 | |||
@@ -119,27 +125,27 @@ | |||
if (min < 10) min = '0' + min; | |||
return min + ":" + second; | |||
}, | |||
searchinfo(){ | |||
if(this.keyword.length==0){ | |||
searchinfo() { | |||
if (this.keyword.length == 0) { | |||
return | |||
}else{ | |||
let parames={ | |||
keyword:this.keyword, | |||
customerId:this.customerId | |||
} | |||
this.$u.post("/corpus/keyWordsMatching", parames).then(res => { | |||
res.forEach(item=>{ | |||
item.Content=JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet=>{ | |||
cet.Content.time=this.formatTime(cet.Content.bg/1000) | |||
if(this.qujian==false){ | |||
cet.Content.text=cet.Content.onebest; | |||
}else{ | |||
cet.Content.text=this.brightKeyword(cet.Content.onebest) | |||
} else { | |||
let parames = { | |||
keyword: this.keyword, | |||
customerId: this.customerId | |||
} | |||
this.$u.post("/corpus/keyWordsMatching", parames).then(res => { | |||
res.forEach(item => { | |||
item.Content = JSON.parse(item.transferContent) | |||
}) | |||
res.forEach(cet => { | |||
cet.Content.time = this.formatTime(cet.Content.bg / 1000) | |||
if (this.qujian == false) { | |||
cet.Content.text = cet.Content.onebest; | |||
} else { | |||
cet.Content.text = this.brightKeyword(cet.Content.onebest) | |||
} | |||
}) | |||
this.listarr=res; | |||
this.listarr = res; | |||
}) | |||
} | |||
}, | |||
@@ -152,26 +158,26 @@ | |||
} | |||
}, | |||
//跳转 | |||
toaidoinfo(item,id,index){ | |||
toaidoinfo(item, id, index) { | |||
uni.setStorageSync("entrance", 2); //写入缓存 | |||
item.customerId=this.customerId; | |||
item.id=id; | |||
item.index=index; | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
item.customerId = this.customerId; | |||
item.id = id; | |||
item.index = index; | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
wx.navigateBack({ //然后返回上一个页面 | |||
delta: 1 | |||
wx.navigateBack({ //然后返回上一个页面 | |||
delta: 1 | |||
}) | |||
} | |||
} | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
.bosdttom{ | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
.bosdttom { | |||
border-bottom: 2px solid #2671E2; | |||
} | |||
</style> |
@@ -15,45 +15,22 @@ | |||
:key="index">录音文件{{index+1}}</view> | |||
</view> | |||
</view> | |||
<view class="audio-container"> | |||
<view class="audio-play" @tap="changePlayState"> | |||
<image class="image" mode="widthFix" :src="audioPlay ? 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/pause.png' : 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/play.png'"></image> | |||
</view> | |||
<view class="audio-slider"> | |||
<view class="audio-time"> | |||
<text>{{currentTimeStr}}</text> | |||
</view> | |||
<slider class="slider" min="0" :max="sliderMax" @change="sliderChangeComplate" block-size="14" | |||
:value="sliderValue" activeColor="blue"></slider> | |||
<view class="audio-time"> | |||
<text>{{timeStr}}</text> | |||
</view> | |||
</view> | |||
</view> | |||
<zaudio :duration="duration" theme="theme4"></zaudio> | |||
</view> | |||
<scroll-view :scroll-top="scrollTop" | |||
lower-threshold='20px' @scrolltolower="ltolower()" :scroll-into-view="scrollId" scroll-y="true" | |||
class="text scroll-Y"> | |||
<scroll-view lower-threshold='20px' @scrolltolower="ltolower()" scroll-y="true" | |||
class="text scroll-Y" :scroll-top="scrollTop" :scroll-into-view="scrollId"> | |||
<!-- 音频识别模块 --> | |||
<view > | |||
<!-- 聊天记录--> | |||
<view class="dialog-block" v-for="(dialog,i) in dialogList" :key="i"> | |||
<view :id="'dialog'+i" class="fileName">录音文件</view> | |||
<view class="text dingweishiy" :id="'dialog'+csdFileindex+'text'+index" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i==0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker" | |||
<view class="text dingweishiy" | |||
v-for="(item,index) in dialog.message" :key="index" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: Math.floor(item.bg/1000) <= playNow && Math.floor(item.ed/1000) > playNow && i==0}" | |||
:data-speaker="item.speaker" | |||
> | |||
<view class="avatar"> | |||
<text v-if="item.speaker == 1" style="color: #60CBEC;">A</text> | |||
<text v-if="item.speaker == 2" style="color: #EC8B47;">B</text> | |||
<text v-if="item.speaker == 3" style="color: #4F861E;">C</text> | |||
<text v-if="item.speaker == 4" style="color: #9F61C8;">D</text> | |||
<text v-if="item.speaker == 5" style="color: #4980C8;">E</text> | |||
<text v-if="item.speaker == 6" style="color: #60CBEC;">F</text> | |||
<text v-if="item.speaker == 7" style="color: #EC8B47;">G</text> | |||
<text v-if="item.speaker == 8" style="color: #4F861E;">H</text> | |||
<text v-if="item.speaker == 9" style="color: #9F61C8;">I</text> | |||
<text :style="[SPEAKERSTYLE(item.speaker)]">{{ item.speaker | toCapital }}</text> | |||
</view> | |||
<view class="content"> | |||
<view v-html="item.onebest"></view> | |||
@@ -71,9 +48,9 @@ | |||
</view> | |||
</view> | |||
<view class="biaoqianya" v-if="startTime==item.bg"> | |||
<view class="biaoqianyaisshow" v-if="biaoqianyaisshow"> | |||
{{biaoqian}} | |||
</view> | |||
<view class="biaoqianyaisshow" v-if="biaoqianyaisshow"> | |||
{{biaoqian}} | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
@@ -168,7 +145,11 @@ | |||
var plugin = requirePlugin("WechatSI") | |||
let manager = plugin.getRecordRecognitionManager(); | |||
import zaudio from '@/components/uniapp-zaudio/zaudio'; | |||
export default { | |||
components: { | |||
zaudio | |||
}, | |||
data() { | |||
return { | |||
dialogList: [], // 录音对话转移列表 | |||
@@ -204,10 +185,6 @@ | |||
audioPlay: false, //当前的播放状态控制 | |||
sliderValue: 0, //进度条最小值 | |||
end: false, | |||
sliderMax: 0, //进度条最大值 | |||
innerAudioContext: "", //播放实例 | |||
currentTimeStr: "00:00", //当前进度的时间 | |||
timeStr: "00:00", //总的时间 | |||
recordPath: "", | |||
csdFileindex:0, | |||
biaoqian:"", | |||
@@ -215,9 +192,14 @@ | |||
startFile:'', | |||
num: 0, //上拉 转写文件下标 | |||
Bnum: 0, //下拉 转写文件下标 | |||
ACTION: Symbol('zaudio'), // 唯一值区分每个页面的方法 | |||
isPageHide: false, // 是否息屏 | |||
duration: '', | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
onLoad(options) { | |||
this.startTime=options.startTime | |||
this.customerId=options.customerId, | |||
this.biaoqian=options.biaoqian; | |||
@@ -225,95 +207,58 @@ | |||
this.getdianzan() | |||
this.getCommentList(); | |||
//注意: 不同的回调方法, 相同的业务函数方法名, 不会相互影响; | |||
this.$zaudio.on('stop', this.ACTION, () => { | |||
console.log('我是强制暂停或关闭小程序音频浮窗触发的') | |||
}) | |||
this.$zaudio.on('seek', this.ACTION, (time) => { | |||
this.sliderChangeComplate(this.TIMEEVENT(time)) | |||
}) | |||
this.$zaudio.on('playing', this.ACTION, (obj) => { | |||
this.duration = obj.duration | |||
this.TimeUpdate(this.TIMEEVENT(obj.current)) | |||
}) | |||
this.$zaudio.on('ended', this.ACTION, e => { | |||
this.qeihuanwenjian() | |||
}) | |||
}, | |||
onShow: function() { | |||
onShow() { | |||
this.initRecord(); | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
this.innerAudioContext.autoplay = false; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
this.getluyinList(); | |||
!this.isPageHide && this.getluyinList(); | |||
}, | |||
// 在组件实例被从页面节点树移除时执行 | |||
destroyed: function() { | |||
if (this.innerAudioContext) { | |||
this.innerAudioContext.destroy(); | |||
} | |||
onHide() { | |||
this.isPageHide = true | |||
}, | |||
onUnload:function(){ | |||
this.innerAudioContext.destroy(); | |||
onUnload(){ | |||
//卸载不需要的业务和获取播放状态的业务,提高页面性能 | |||
this.$zaudio.off('seek', this.ACTION); | |||
this.$zaudio.off('stop', this.ACTION); | |||
this.$zaudio.off('playing', this.ACTION); | |||
this.$zaudio.off('ended', this.ACTION); | |||
}, | |||
methods: { | |||
onPlay(){ | |||
this.innerAudioContext.onPlay(() => { | |||
// 播放监听 | |||
console.log('播放!'); | |||
this.audioPlay = true; | |||
}); | |||
}, | |||
onPause(){ | |||
this.innerAudioContext.onPause(() => { | |||
// 暂停监听 | |||
console.log('暂停播放!'); | |||
this.audioPlay = false | |||
}); | |||
}, | |||
onCanplay() { | |||
this.innerAudioContext.onCanplay((callback) => { | |||
console.log("缓冲回调",this.innerAudioContext.duration); | |||
}) | |||
}, | |||
onEnded(){ | |||
this.innerAudioContext.onEnded(() => { | |||
// 结束播放监听 | |||
console.log('播放结束!'); | |||
this.audioPlay = false; | |||
this.qeihuanwenjian() | |||
}); | |||
}, | |||
onSeeking(){ | |||
this.innerAudioContext.onSeeking((res) => { | |||
console.log("进行跳转", res); | |||
}) | |||
}, | |||
onSeeked(){ | |||
this.innerAudioContext.onSeeked((res) => { | |||
console.log("结束跳转", res); | |||
this.$forceUpdate() | |||
}); | |||
}, | |||
TimeUpdate(){ | |||
this.innerAudioContext.onTimeUpdate(() => { | |||
const { | |||
currentTime, | |||
duration | |||
} = this.innerAudioContext; | |||
this.playNow = parseInt(currentTime * 1000) | |||
if (this.dialogList.length == 0) { | |||
} else { | |||
const message = this.dialogList[0].message | |||
for (let i = 0; i < message.length; i++) { | |||
if (Number(message[i].bg) < this.playNow && Number(message[i].ed) > this.playNow) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + i; | |||
break; | |||
} | |||
TimeUpdate(currentTime) { | |||
this.playNow = Number(currentTime) | |||
if (this.dialogList.length == 0) { | |||
return | |||
} else { | |||
const message = this.dialogList[0].message; | |||
if (!message) return | |||
for (let i = 0; i < message.length; i++) { | |||
if ((Math.floor(message[i].bg / 1000) <= this.playNow && this.playNow < Math.floor(message[i].ed / 1000))) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
if (i < message.length - 1 && Math.floor(message[i].ed / 1000) < this.playNow && this.playNow < Math.floor(message[i + 1].bg / 1000)) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
} | |||
const currTimeStr = this.formatTime(currentTime); | |||
this.sliderValue = parseInt(currentTime); | |||
// 变动的时间 | |||
this.currentTimeStr = currTimeStr; | |||
//进度条最大值 | |||
this.sliderMax = this.luyinList[this.csdFileindex].recordDuration; | |||
this.$forceUpdate() | |||
}); | |||
} | |||
this.$forceUpdate() | |||
}, | |||
//下一页 | |||
@@ -327,12 +272,6 @@ | |||
return | |||
}else { | |||
this.num=this.num+1; | |||
uni.showLoading({ | |||
title: '加载中' | |||
}); | |||
setTimeout(function() { | |||
uni.hideLoading(); | |||
}, 2000); | |||
uni.request({ | |||
url: config.service.getCorpusAnalysis + '?corpusId=' + this.luyinList[this.num].id+"&customerId="+this.customerId, //仅为示例,并非真实接口地址。 | |||
method: "GET", | |||
@@ -343,9 +282,6 @@ | |||
success: (data) => { | |||
if (data.data.code == 10000) { | |||
if (data.data.data.audioContent.length == 0) { | |||
setTimeout(function() { | |||
uni.hideLoading(); | |||
}, 2000); | |||
} else { | |||
const jsonInfo = JSON.parse(data.data.data.audioContent); | |||
this.dialogList.push({ | |||
@@ -432,13 +368,11 @@ | |||
if(cet.id==this.startFile){ | |||
this.csdFileindex=index; | |||
this.recordPath = res[index].recordPath | |||
this.sliderMax = this.getTime(res[index].recordDuration) | |||
this.timeStr = this.getTime(res[index].recordDuration) | |||
this.date=res[index].receptionTime | |||
this.num=index;//下拉起始位置 | |||
this.Bnum=index; | |||
this.creatAudio(); | |||
this.luyinList = res; | |||
this.zyAudio(); | |||
this.getCorpusAnalysis() | |||
var itc=parseInt(this.startTime/1000) | |||
this.adasdasdasd(itc) | |||
@@ -451,10 +385,7 @@ | |||
}, | |||
//首次跳转 | |||
adasdasdasd(e) { | |||
const currTimeStr = this.formatTime(e) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e); | |||
this.innerAudioContext.play(); | |||
this.stepPlay(e) | |||
}, | |||
//录音文件切换隐藏 | |||
showFile() { | |||
@@ -484,7 +415,6 @@ | |||
const that = this; | |||
manager.onStart = function(res) { | |||
that.isRecording = true; | |||
// this.voiceState = "onStart:" + res.msg + "正在录音" | |||
}; | |||
//有新的识别内容返回,则会调用此事件 | |||
manager.onRecognize = (res) => { | |||
@@ -507,30 +437,14 @@ | |||
uni.hideLoading(); | |||
} | |||
}, | |||
// 录音暂停播放 | |||
changePlayState() { | |||
if (this.audioPlay == false) { | |||
this.innerAudioContext.play(); | |||
} else { | |||
this.innerAudioContext.pause() | |||
} | |||
}, | |||
//音频前进回退 | |||
sliderChangeComplate(e) { | |||
const currTimeStr = this.formatTime(e.detail.value) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e.detail.value); | |||
this.innerAudioContext.play(); | |||
}, | |||
sliderChangeComplate(currentTime) {}, | |||
// 获取转义后的对话结果 | |||
getCorpusAnalysis(){ | |||
this.dialogList = []; | |||
uni.showLoading({ | |||
title: '加载中' | |||
}); | |||
uni.request({ | |||
url: config.service.getCorpusAnalysis + '?corpusId=' + this.luyinList[this.csdFileindex].id+"&customerId="+this.customerId, //仅为示例,并非真实接口地址。 | |||
method:"GET", | |||
@@ -547,22 +461,9 @@ | |||
setTimeout(function () { | |||
uni.hideLoading(); | |||
}, 2000); | |||
}else{ | |||
uni.hideLoading(); | |||
uni.showModal({ | |||
title: '提示', | |||
content: '请求数据失败,请重新尝试', | |||
showCancel: false | |||
}); | |||
} | |||
}else{} | |||
}, | |||
fail(error) { | |||
uni.hideLoading(); | |||
uni.showModal({ | |||
title: '提示', | |||
content: '网络异常,请重新尝试', | |||
showCancel: false | |||
}); | |||
return false; | |||
} | |||
}); | |||
@@ -574,32 +475,15 @@ | |||
filechange(item, i) { | |||
this.num=i;//下拉起始位置 | |||
this.Bnum=i; | |||
console.log("下拉下标",this.Bnum) | |||
console.log("上拉下标",this.num) | |||
this.innerAudioContext.destroy() | |||
this.csdFileindex=i; | |||
this.recordPath = item.recordPath; | |||
this.sliderMax = this.getTime(item.recordDuration); | |||
this.timeStr = this.getTime(item.recordDuration); | |||
this.date=item.receptionTime; | |||
this.isshowFile=false; | |||
this.creatAudio() | |||
setTimeout(() => { | |||
this.$zaudio.operate(i) | |||
}, 50) | |||
this.getCorpusAnalysis() | |||
}, | |||
//录音实例 | |||
creatAudio() { | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
this.innerAudioContext.autoplay = true; | |||
this.innerAudioContext.src = this.recordPath; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
}, | |||
// 自动播放下一个文件 | |||
qeihuanwenjian(){ | |||
let index=this.csdFileindex+1; | |||
@@ -764,7 +648,30 @@ | |||
asd.isshow=false; | |||
}) | |||
}) | |||
} | |||
}, | |||
//录音实例 | |||
zyAudio() { | |||
let data = this.luyinList.map((item, index) => { | |||
return { | |||
src: item.recordPath, | |||
title: `录音文件${index + 1}`, | |||
singer: '', | |||
coverImgUrl: '' | |||
} | |||
}) | |||
this.$zaudio.setAudio(data) | |||
//渲染第一首音频 | |||
this.$zaudio.setRender(0) | |||
}, | |||
// 跳转指定位置播放 | |||
stepPlay(t) { | |||
this.$zaudio.seek(t) | |||
if (this.$zaudio.paused) { | |||
this.$zaudio.operate() | |||
} | |||
}, | |||
} | |||
}; | |||
</script> | |||
@@ -1323,14 +1230,14 @@ | |||
} | |||
.scroll-Y .text.active .content { | |||
color: #38FFF1; | |||
color: #38FFF1 !important; | |||
position: relative; | |||
} | |||
.scroll-Y .text.active[data-speaker="2"] .content, | |||
.scroll-Y .text.active[data-speaker="4"] .content, | |||
.scroll-Y .text.active[data-speaker="6"] .content { | |||
color: #FF7538; | |||
color: #FF7538 !important; | |||
position: relative; | |||
} | |||
@@ -32,7 +32,7 @@ | |||
<!-- 聊天记录--> | |||
<view class="dialog-block" v-for="(dialog,i) in dialogList" :key="i"> | |||
<view :id="'dialog'+i" class="fileName">录音文件</view> | |||
<view class="text dingweishiy" :id="'dialog'+csdFileindex+'text'+index" | |||
<view class="text dingweishiy" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i==0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker" | |||
> | |||
@@ -35,13 +35,15 @@ | |||
listarr:[], | |||
keyword:'', | |||
skpl:'', | |||
disabled:false | |||
disabled:false, | |||
tipsFncName: '', // 通知其他页面的方法名称 | |||
}; | |||
}, | |||
onLoad(options) { | |||
this.customerId = options.customerId; | |||
this.keyword=options.keyword; | |||
this.skpl=options.skpl; | |||
if (options.UpDateEvent) this.tipsFncName = options.UpDateEvent | |||
if(this.skpl==2){ | |||
this.searchinfo() | |||
this.disabled=true; | |||
@@ -98,6 +100,7 @@ | |||
}else{ | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
if (this.tipsFncName) uni.$emit(this.tipsFncName, item) | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
@@ -47,7 +47,7 @@ | |||
<view class="dialog-block" v-for="(dialog,i) in dialogList" :key="i"> | |||
<view :id="'dialog'+i" class="fileName">录音文件</view> | |||
<view class="text" :id="'dialog'+csdFileindex+'text'+index" | |||
<view class="text" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i== 0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker" | |||
> | |||
@@ -13,21 +13,7 @@ | |||
</view> | |||
</view> | |||
<view class="call_record_time_one" >接待时长 {{alltimeStr}}</view> | |||
<view class="audio-container"> | |||
<view class="audio-play" @tap="changePlayState"> | |||
<image class="image" mode="widthFix" :src="audioPlay ? 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/pause.png' : 'https://qufang.oss-cn-beijing.aliyuncs.com/upload/icon/xcx/jjycrm/play.png'"></image> | |||
</view> | |||
<view class="audio-slider"> | |||
<view class="audio-time"> | |||
<text>{{currentTimeStr}}</text> | |||
</view> | |||
<slider class="slider" min="0" :max="sliderMax" @change="sliderChangeComplate" block-size="14" | |||
:value="sliderValue" activeColor="blue"></slider> | |||
<view class="audio-time"> | |||
<text>{{timeStr}}</text> | |||
</view> | |||
</view> | |||
</view> | |||
<zaudio theme="theme4"></zaudio> | |||
</view> | |||
<scroll-view :scroll-top="scrollTop" lower-threshold='100px' @scrolltolower="ltolower()" | |||
upper-threshold='40px' @scrolltoupper="rolltoupper()" | |||
@@ -40,47 +26,15 @@ | |||
<view :id="'dialog'+i" class="fileName">录音文件</view> | |||
<view class="text" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i== 0}" | |||
:class="{active: Math.floor(item.bg / 1000) < playNow && Math.floor(item.ed / 1000) > playNow && i== 0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker" | |||
> | |||
<view class="avatar"> | |||
<view class="avatar"> | |||
<view v-if="item.speaker == 1" style="color: #60CBEC;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>A</text> | |||
</view> | |||
<view v-if="item.speaker == 2" style="color: #EC8B47;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>B</text> | |||
</view> | |||
<view v-if="item.speaker == 3" style="color: #4F861E;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>C</text> | |||
</view> | |||
<view v-if="item.speaker == 4" style="color: #9F61C8;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>D</text> | |||
</view> | |||
<view v-if="item.speaker == 5" style="color: #4980C8;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>E</text> | |||
</view> | |||
<view v-if="item.speaker == 6" style="color: #60CBEC;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>F</text> | |||
</view> | |||
<view v-if="item.speaker == 7" style="color: #EC8B47;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>G</text> | |||
</view> | |||
<view v-if="item.speaker == 8" style="color: #4F861E;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>H</text> | |||
</view> | |||
<view v-if="item.speaker == 9" style="color: #9F61C8;"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"></image> | |||
<text v-else>I</text> | |||
<view :style="[SPEAKERSTYLE(item.speaker)]"> | |||
<image v-if="item.isShow == 0" :src="Aimg.replace(/[\r\n]/g,'')" mode="widthFix"> | |||
</image> | |||
<text v-else>{{ item.speaker | toCapital }}</text> | |||
</view> | |||
</view> | |||
</view> | |||
@@ -179,7 +133,9 @@ | |||
var plugin = requirePlugin("WechatSI") | |||
let manager = plugin.getRecordRecognitionManager(); | |||
import zaudio from '@/components/uniapp-zaudio/zaudio'; | |||
export default { | |||
components: { zaudio }, | |||
data() { | |||
return { | |||
Aimg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAMAAAC5zwKfAAACqVBMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9/f3////9/f39/f3////////9/f3////////////9/f3////9/f39/f3////9/f3////////9/f3////9/f3////////////////9/f39/f3////////9/f39/f3////9/f39/f3////////9/f39/f3////////9/f39/f39/f3////////////////+/v7+/v7////+/v7////+/v7////+/v7+/v7////////+/v7+/v7////+/v7////+/v7////////////////////////////+/v7////+/v7////+/v7+/v7////////////+/v7////+/v7////+/v7+/v7////////+/v7////+/v7////////+/v7////////+/v7////+/v7+/v7+/v7////////+/v7+/v7////+/v7+/v7////+/v7////+/v7////+/v7////+/v7+/v7////+/v7+/v7////+/v7////+/v7////+/v7+/v7////+/v5jdC9iAAAA4nRSTlMAAQIDBAUGBwgLDA0ODxARExQVFhgbHB4fICEiIyQmJygpKy4wMTIzNDY3ODk6Oz0+P0BBQkRGR0lKTE5PUFFTVFVXWFlcXV9gYWJjZWZnaGlqa2xtbm9wcXJzdHV2d3h6e319foGBgoODh4mKiouMjI2QkZKSk5OUlpeYmZmam5ycnZ+foKGio6SmqKmpq6yur7CwsbGytba5uru8wMDBwcLCw8XGx8jJysrLzM7P0dLT1dXW1tfY2drc3N7f4OHh5Obm5+jp6uvs7vDx8vLz8/T09fX29/f4+fn6+vz8/f7+RVDt+wAAA55JREFUGBntwf9/1HMAB/DX7XYbuXWV1cyMoixfugrRGNXytW33pbVdJ83XkiMLSb4LJd/zZUi0SKT5FmGS77HUVaixnHP2+kt8vt3Zbp/3+7P3XR5+8XziP1E4uiYcrh1bjMNi6NzXumnoeX3eSOSrpHUv+zi0ogJ5qd3JLN1XuJGzwqW0sW4oclT0Im19XIqcuNdQ4D0vcnEDhdYgB2f+SbFZUHbEdkrsLYeqFko9CEVH7qJUohxqLqODO6BmLR18XwAVRQfpZDxUnExHjVBRR0eroGIZHX0AFe10tA8qdtNZIRR00VEPVLxLRzuh4jk62gIVy+joSaiI0tECqPDT0blQ4f6RDpI+KHmYDjZBzWQ6aIaibZSK+6BoOqViUOXqoER8BJSdlqJYFDm4h0LveJAD7+cUiFciJ1U/01aiGjk65zfaSF6EnE3azQEO1iAPFZuZZes45MUT3cM+emLFyNfwK3fQ8k1sFA6L0cElTzx9d1OVC/8bNG/gzY+GQaKk461gCQZr8iMHSNZD4nySv6wYj0EYFv2UhqcgcTsN70ePhtzER3+lJe6BxXP9jTctvrl1yS1jkLaNlkTbBR6IlF3dyT78sHh+oqkSlrJe/uOH1jGw4apem2I/1yLtGRo6kRZiP73t57mQxb+Z2dqRdikNtyLtBWb78Cz05bomyQH+KIGljIYaWNxxDtC72ouMgsdpZzosHhqqYDmFdraOQNpttHUfLKU0TITlKtra6IZpCu3tgMVPQx0sG2ivDqaVFDgOppk0LIbJm6C9DTB1UCAMU4SGZ2GqocAumL6jQBtMMRq2wLScAik3dMV/UWB/EQwrafgSpk6KlEJ3LIXOgGE9DQdgqKDQSdBNoNAiGL6i6SjowhSaAt1UCm2CzpOk6QTonqfQJdBdSKGkD5pKWqZCU7iHQtdB10KxWmjOpqUJmtMp9gB091LsIWiCtCyFZiHFXoZuHcW+hiZGy0vQvE2xT6DbTolKAI/R8hmA4SmKdUG3jxIhAG/QkigAZlAi6QJQTJk2AF1MGwXcRRkfgJGU2V8EHzP8wBeUqQQwllKTcCozpuFESk0AMJNSC3AxM8KYT6lpAFootRGLmLEQ6ynVCCBAqcSQ1cy4f8ghSs0HcMzvlKp+lRmvVFMqNQ6aaIoyd3Yy49vllOmuh+H4WZFIpFnTpJmjadTM1oQ1oVAgFNQENA0N9f01BIKh8OzGOU3NkbmXzwuV41/wNztgHKhu7WKTAAAAAElFTkSuQmCC", | |||
@@ -223,10 +179,15 @@ | |||
itemobj:{}, | |||
textindex:0,//下拉 转写文件下标 | |||
toptextindex:0,//上拉 转写文件下标 | |||
timer:null | |||
timer:null, | |||
ACTION: Symbol('zaudio'), // 唯一值区分每个页面的方法 | |||
isPageHide: false, // 是否息屏 | |||
duration: '', | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
onLoad(options) { | |||
this.status = options.status; | |||
this.customerId = options.customerId; | |||
this.itemobj=JSON.parse(options.itemobj); | |||
@@ -240,62 +201,54 @@ | |||
this.timer=setTimeout(function(){ | |||
that.addHot() | |||
},30000) | |||
//注意: 不同的回调方法, 相同的业务函数方法名, 不会相互影响; | |||
this.$zaudio.on('stop', this.ACTION, () => { | |||
console.log('我是强制暂停或关闭小程序音频浮窗触发的') | |||
}) | |||
this.$zaudio.on('seek', this.ACTION, (time) => { | |||
this.sliderChangeComplate(this.TIMEEVENT(time)) | |||
}) | |||
this.$zaudio.on('playing', this.ACTION, (obj) => { | |||
this.TimeUpdate(this.TIMEEVENT(obj.current)) | |||
}) | |||
uni.$on('THEFULLTEXT2', info => { | |||
this.getluyinList(info) | |||
}) | |||
}, | |||
onShow: function() { | |||
// wx.enableAlertBeforeUnload({ | |||
// message: "是否确认退出详情页面?", | |||
// success: function (res) { | |||
// console.log("方法注册成功:", res); | |||
// }, | |||
// fail: function (errMsg) { | |||
// console.log("方法注册失败:", errMsg); | |||
// }, | |||
// }); | |||
onShow() { | |||
//实时渲染当前的播放状态 | |||
this.$zaudio.syncRender() | |||
this.initRecord(); | |||
if(this.stateisshow==2){ | |||
var info =this.itemobj; | |||
}else{ | |||
var pages = getCurrentPages(); | |||
var currPage = pages[pages.length - 1]; //当前页面 | |||
var info = currPage.data.info; | |||
} | |||
console.log(info,656456546) | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
this.innerAudioContext.autoplay = false; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
this.getluyinList(info); | |||
!this.isPageHide && this.getluyinList(info); | |||
}, | |||
// 在组件实例被从页面节点树移除时执行 | |||
destroyed: function() { | |||
clearTimeout(this.timer) | |||
//暂停 | |||
// this.innerAudioContext.pause() | |||
// 销毁 | |||
this.innerAudioContext.destroy(); | |||
onHide() { | |||
this.isPageHide = true | |||
}, | |||
// 销毁实例 | |||
onUnload: function() { | |||
//暂停 | |||
// this.innerAudioContext.pause() | |||
// 销毁 | |||
this.innerAudioContext.destroy(); | |||
onUnload() { | |||
uni.$off('THEFULLTEXT2') | |||
//卸载不需要的业务和获取播放状态的业务,提高页面性能 | |||
this.$zaudio.off('seek', this.ACTION); | |||
this.$zaudio.off('stop', this.ACTION); | |||
this.$zaudio.off('playing', this.ACTION); | |||
}, | |||
methods: { | |||
toKeywordsearch(){ | |||
this.innerAudioContext.destroy(); | |||
uni.navigateTo({ | |||
url: '/pages/learning/Thefulltext/search?customerId='+this.customerId +"&status="+this.status+"&skpl="+"2" | |||
url: '/pages/learning/Thefulltext/search?customerId='+this.customerId +"&status="+this.status+"&skpl="+"2" + '&UpDateEvent=THEFULLTEXT2' | |||
}) | |||
}, | |||
getView(){ | |||
@@ -331,70 +284,25 @@ | |||
}); | |||
}); | |||
}, | |||
onPause(){ | |||
this.innerAudioContext.onPause(() => { | |||
wx.disableAlertBeforeUnload({ | |||
success:function(res){ | |||
console.log(res) | |||
}, | |||
fail:function(e){ | |||
console.log(e) | |||
} | |||
}); | |||
// 暂停监听 | |||
console.log('暂停播放!'); | |||
this.audioPlay = false | |||
}); | |||
}, | |||
onCanplay() { | |||
this.innerAudioContext.onCanplay((callback) => { | |||
console.log("缓冲回调",this.innerAudioContext.duration); | |||
}) | |||
}, | |||
onEnded(){ | |||
this.innerAudioContext.onEnded(() => { | |||
// 结束播放监听 | |||
console.log('播放结束!'); | |||
this.audioPlay = false; | |||
}); | |||
}, | |||
onSeeking(){ | |||
this.innerAudioContext.onSeeking((res) => { | |||
console.log("进行跳转", res); | |||
}) | |||
}, | |||
onSeeked(){ | |||
this.innerAudioContext.onSeeked((res) => { | |||
console.log("结束跳转", res); | |||
this.$forceUpdate() | |||
}); | |||
}, | |||
TimeUpdate(){ | |||
this.innerAudioContext.onTimeUpdate(() => { | |||
const { | |||
currentTime, | |||
duration | |||
} = this.innerAudioContext; | |||
this.playNow = parseInt(currentTime * 1000) | |||
if (this.dialogList.length == 0) { | |||
} else { | |||
const message = this.dialogList[0].message; | |||
for (let i = 0; i < message.length; i++) { | |||
if (Number(message[i].bg) < this.playNow && Number(message[i].ed) > this.playNow) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
TimeUpdate(currentTime) { | |||
this.playNow = Number(currentTime) | |||
if (this.dialogList.length == 0) { | |||
return | |||
} else { | |||
const message = this.dialogList[0].message; | |||
if (!message) return | |||
for (let i = 0; i < message.length; i++) { | |||
if ((Math.floor(message[i].bg / 1000) <= this.playNow && this.playNow < Math.floor(message[i].ed / 1000))) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
if (i < message.length - 1 && Math.floor(message[i].ed / 1000) < this.playNow && this.playNow < Math.floor(message[i + 1].bg / 1000)) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
} | |||
const currTimeStr = this.formatTime(currentTime); | |||
this.sliderValue = parseInt(currentTime); | |||
// 变动的时间 | |||
this.currentTimeStr = currTimeStr; | |||
//进度条最大值 | |||
this.sliderMax = this.luyinList[this.csdFileindex].recordDuration; | |||
this.$forceUpdate() | |||
}); | |||
} | |||
this.$forceUpdate() | |||
}, | |||
//下一页 | |||
ltolower() { | |||
@@ -494,31 +402,22 @@ | |||
if(info.bg!=0){ | |||
this.luyinList = res; | |||
this.recordPath = res[0].recordPath | |||
this.sliderMax = this.getTime(res[0].recordDuration) | |||
this.timeStr = this.getTime(res[0].recordDuration) | |||
this.date = res[0].receptionTime; | |||
this.getCorpusAnalysis(info); | |||
this.creatAudio() | |||
this.stepPlay(Math.floor(info.bg / 1000)) | |||
}else{ | |||
this.luyinList = res; | |||
this.recordPath = res[0].recordPath | |||
this.sliderMax = this.getTime(res[0].recordDuration) | |||
this.timeStr = this.getTime(res[0].recordDuration) | |||
this.date = res[0].receptionTime; | |||
this.getCorpusAnalysis(info); | |||
this.creatAudio() | |||
this.zyAudio() | |||
} | |||
} | |||
}) | |||
}, | |||
//搜索跳转 | |||
adasdasdasd(e) { | |||
const currTimeStr = this.formatTime(e) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e); | |||
this.innerAudioContext.play(); | |||
this.stepPlay(e) | |||
}, | |||
// 获取转义后的对话结果 | |||
@@ -538,7 +437,6 @@ | |||
//下拉标记点 | |||
this.toptextindex=data.data.data.index; | |||
console.log(info.onebest+":66666666666666666666666666666") | |||
jsonInfo.forEach(item=>{ | |||
item.message=JSON.parse(item.onebest) | |||
item.backindex=this.csdFileindex; | |||
@@ -552,40 +450,17 @@ | |||
}) | |||
this.newluyinList=jsonInfo; | |||
this.dialogList.push(jsonInfo[this.textindex]); | |||
var itc=parseInt(info.bg/1000) | |||
this.adasdasdasd(itc) | |||
this.adasdasdasd(Math.floor(info.bg / 1000)) | |||
} | |||
}) | |||
}, | |||
getTime(time) { | |||
return util.formatSecond(time) | |||
}, | |||
//录音实例 | |||
creatAudio() { | |||
this.innerAudioContext = uni.createInnerAudioContext(); | |||
this.innerAudioContext.autoplay = true; | |||
this.innerAudioContext.src = this.recordPath; | |||
this.innerAudioContext.title = '音频'; | |||
this.onPlay() | |||
this.onPause() | |||
this.onCanplay() | |||
this.onEnded() | |||
this.onSeeking() | |||
this.onSeeked() | |||
this.TimeUpdate() | |||
}, | |||
// 录音暂停播放 | |||
changePlayState() { | |||
if (this.audioPlay == false) { | |||
this.innerAudioContext.play(); | |||
} else { | |||
this.innerAudioContext.pause() | |||
} | |||
}, | |||
//音频前进回退 | |||
sliderChangeComplate(e) { | |||
let platetime=e.detail.value*1000; | |||
sliderChangeComplate(currentTime) { | |||
let platetime=currentTime*1000; | |||
this.dialogList=[] | |||
uni.request({ | |||
url: config.service.fastForward + '?corpusId=' + this.luyinList[this.csdFileindex].id+"&bg="+platetime, //仅为示例,并非真实接口地址。 | |||
@@ -598,10 +473,9 @@ | |||
this.textindex=data.data.data.index; | |||
this.toptextindex=data.data.data.index; | |||
this.dialogList.push(this.newluyinList[data.data.data.index]) | |||
const currTimeStr = this.formatTime(e.detail.value) | |||
this.currentTimeStr = currTimeStr | |||
this.innerAudioContext.seek(e.detail.value); | |||
this.innerAudioContext.play(); | |||
if (this.$zaudio.paused) { | |||
this.$zaudio.operate() | |||
} | |||
} | |||
}) | |||
}, | |||
@@ -798,11 +672,31 @@ | |||
this.answerId = null; | |||
this.answerUserId = null; | |||
this.textareaFocus = false; | |||
// this.dialogList.forEach(res=>{ | |||
// res.message.forEach(asd=>{ | |||
// asd.isshow=false; | |||
// }) | |||
// }) | |||
}, | |||
//录音实例 | |||
zyAudio() { | |||
let data = [ | |||
{ | |||
src: this.recordPath, | |||
title: '录音音频', | |||
singer: '', | |||
coverImgUrl: '' | |||
} | |||
] | |||
this.$zaudio.setAudio(data) | |||
//渲染第一首音频 | |||
this.$zaudio.setRender(0) | |||
}, | |||
// 跳转指定位置播放 | |||
stepPlay(t) { | |||
this.$zaudio.seek(t) | |||
if (this.$zaudio.paused) { | |||
this.$zaudio.operate() | |||
} | |||
} | |||
} | |||
}; | |||
@@ -1289,14 +1183,14 @@ | |||
} | |||
.scroll-Y .text.active .content { | |||
color: #38FFF1; | |||
color: #FF7538 !important; | |||
position: relative; | |||
} | |||
.scroll-Y .text.active[data-speaker="2"] .content, | |||
.scroll-Y .text.active[data-speaker="4"] .content, | |||
.scroll-Y .text.active[data-speaker="6"] .content { | |||
color: #FF7538; | |||
color: #FF7538 !important; | |||
position: relative; | |||
} | |||
@@ -35,13 +35,16 @@ | |||
listarr:[], | |||
keyword:'', | |||
skpl:'', | |||
disabled:false | |||
disabled:false, | |||
tipsFncEvent: "", | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
onLoad(options) { | |||
this.customerId = options.customerId; | |||
this.keyword=options.keyword; | |||
this.skpl=options.skpl; | |||
if (options.UpDateEvent) this.tipsFncEvent = options.UpDateEvent | |||
}, | |||
methods: { | |||
formatTime(num) { | |||
@@ -92,6 +95,7 @@ | |||
}else{ | |||
let pages = getCurrentPages() //获取当前页面栈的信息 | |||
let prevPage = pages[pages.length - 2] //获取上一个页面 | |||
uni.$emit(this.tipsFncEvent, item) | |||
prevPage.setData({ //把需要回传的值保存到上一个页面 | |||
info: item | |||
}); | |||
@@ -26,9 +26,7 @@ | |||
src="../../static/images/nopike.png" mode=""></image> | |||
</view> | |||
</view> | |||
<yz-audio :nowFileTime="nowTime" class="audio-container" ref="zyAudio" @ended="qeihuanwenjian" | |||
@timeUpdate="TimeUpdate" @sliderChangeComplate="sliderChangeComplate"></yz-audio> | |||
<zaudio :duration="duration" theme="theme4"></zaudio> | |||
</view> | |||
<scroll-view :scroll-top="scrollTop" lower-threshold='20px' @scrolltolower="ltolower()" | |||
:scroll-into-view="scrollId" scroll-y="true" class="text scroll-Y"> | |||
@@ -49,7 +47,7 @@ | |||
<!-- {{i+1}} --> | |||
</view> | |||
<view class="text" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i==0}" | |||
:class="{active:Math.floor(item.bg/1000) <= playNow && Math.floor(item.ed/1000) > playNow && i==0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker"> | |||
<view class="avatar"> | |||
<text :style="[SPEAKERSTYLE(item.speaker)]">{{ item.speaker | toCapital }}</text> | |||
@@ -177,7 +175,11 @@ | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
import zaudio from '@/components/uniapp-zaudio/zaudio'; | |||
export default { | |||
components: { | |||
zaudio | |||
}, | |||
data() { | |||
return { | |||
recordPath: "", | |||
@@ -246,17 +248,37 @@ | |||
}; | |||
}, | |||
computed: { | |||
nowTime() { | |||
return this.getTime(this.luyinList[this.csdFileindex].recordDuration) | |||
}, | |||
}, | |||
onLoad: function(options) { | |||
onLoad(options) { | |||
this.status = options.status; | |||
this.customerId = options.customerId; | |||
this.itemobj = uni.getStorageSync('searchobj'); | |||
this.stateisshow = options.stateisshow; | |||
this.$zaudio.autoPlay = true | |||
//注意: 不同的回调方法, 相同的业务函数方法名, 不会相互影响; | |||
this.$zaudio.on('stop', this.ACTION, () => { | |||
console.log('我是强制暂停或关闭小程序音频浮窗触发的') | |||
}) | |||
this.$zaudio.on('seek', this.ACTION, (time) => { | |||
this.sliderChangeComplate(this.TIMEEVENT(time)) | |||
}) | |||
this.$zaudio.on('playing', this.ACTION, (obj) => { | |||
this.TimeUpdate(this.TIMEEVENT(obj.current)) | |||
}) | |||
this.$zaudio.on('ended', this.ACTION, e => { | |||
this.$nextTick(() => { | |||
this.scrollId = ""; | |||
}) | |||
this.qeihuanwenjian() | |||
}) | |||
this.$zaudio.on('error', this.ACTION, e => { | |||
console.log(e, '加载失败') | |||
}) | |||
uni.$on('DETAILSINIT', info => { | |||
this.init(info) | |||
}) | |||
}, | |||
onShow() { | |||
@@ -273,16 +295,25 @@ | |||
} | |||
if (this.stateisshow == 2) { | |||
var info = this.itemobj; | |||
} else { | |||
var pages = getCurrentPages(); | |||
var currPage = pages[pages.length - 1]; //当前页面 | |||
var info = currPage.data.info; | |||
} | |||
this.gituserlist() | |||
this.init(info) | |||
!this.isPageHide && this.init(info) | |||
}, | |||
onHide() { | |||
this.isPageHide = true | |||
}, | |||
onUnload() { | |||
//卸载不需要的业务和获取播放状态的业务,提高页面性能 | |||
this.$zaudio.off('seek', this.ACTION); | |||
this.$zaudio.off('stop', this.ACTION); | |||
this.$zaudio.off('playing', this.ACTION); | |||
this.$zaudio.off('ended', this.ACTION); | |||
this.$zaudio.off('error', this.ACTION); | |||
}, | |||
methods: { | |||
effectiveAdd() { | |||
if (this.effectiveindex == 4) { | |||
@@ -363,22 +394,24 @@ | |||
this.stateisshow = 1; | |||
uni.navigateTo({ | |||
url: '/pages/learning/Keywordsearch?customerId=' + this.customerId + "&status=" + this.status + | |||
"&skpl=" + "1" | |||
"&skpl=" + "1" + '$UpDateEvent=DETAILSINIT' | |||
}) | |||
}, | |||
TimeUpdate(e) { | |||
const { | |||
currentTime, | |||
duration | |||
} = e; | |||
this.playNow = parseInt(currentTime * 1000) | |||
TimeUpdate(currentTime) { | |||
this.playNow = Number(currentTime) | |||
if (this.dialogList.length == 0) { | |||
return | |||
} else { | |||
const message = this.dialogList[0].message | |||
const message = this.dialogList[0].message; | |||
if (!message) return | |||
for (let i = 0; i < message.length; i++) { | |||
if (Number(message[i].bg) < this.playNow && Number(message[i].ed) > this.playNow) { | |||
if ((Math.floor(message[i].bg / 1000) <= this.playNow && this.playNow < Math.floor(message[i].ed / 1000))) { | |||
console.log(message[i]) | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
if (i < message.length - 1 && Math.floor(message[i].ed / 1000) < this.playNow && this.playNow < Math.floor(message[i + 1].bg / 1000)) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
@@ -413,7 +446,7 @@ | |||
this.date = res[index].receptionTime; | |||
this.isshowFile = false; | |||
this.getCorpusAnalysis(info); | |||
var itc = parseInt(info.bg / 1000) | |||
var itc = info.bg / 1000 | |||
this.adasdasdasd(itc) | |||
} | |||
}) | |||
@@ -423,24 +456,14 @@ | |||
this.luyinList = res; | |||
this.getCorpusAnalysis() | |||
} | |||
console.log(res, '打印音频列表内容') | |||
this.zyAudio() | |||
} | |||
}) | |||
}, | |||
//录音实例 | |||
zyAudio() { | |||
console.log('this.recordPath', this.recordPath) | |||
this.$refs.zyAudio.setSrc(this.recordPath) | |||
}, | |||
//搜索跳转 | |||
adasdasdasd(e) { | |||
this.$refs.zyAudio.seek(e) | |||
this.$refs.zyAudio.play(); | |||
this.stepPlay(e) | |||
}, | |||
//下一页 | |||
ltolower() { | |||
@@ -969,10 +992,12 @@ | |||
}, | |||
//音频前进回退 | |||
sliderChangeComplate(e) { | |||
this.$refs.zyAudio.seek(e.detail.value); | |||
this.$refs.zyAudio.play(); | |||
sliderChangeComplate(currentTime) { | |||
// 暂时没有处理 | |||
// this.$refs.zyAudio.seek(e.detail.value); | |||
// this.$refs.zyAudio.play(); | |||
}, | |||
//长按点击播放 | |||
clickbofang(dialog, item) { | |||
this.dialogList.forEach(res => { | |||
@@ -983,8 +1008,7 @@ | |||
this.$forceUpdate() | |||
if (dialog == this.csdFileindex) { | |||
let time = parseInt(item.bg / 1000) | |||
this.$refs.zyAudio.seek(time); | |||
this.$refs.zyAudio.play(); | |||
this.stepPlay(time); | |||
return | |||
} else { | |||
let time = parseInt(item.bg / 1000) | |||
@@ -992,9 +1016,7 @@ | |||
this.recordPath = this.luyinList[dialog].recordPath; | |||
this.date = this.luyinList[dialog].receptionTime; | |||
this.getCorpusAnalysis() | |||
this.$refs.zyAudio.seek(time); | |||
this.$refs.zyAudio.play(); | |||
this.stepPlay(time); | |||
} | |||
}, | |||
// 文件切换播放 | |||
@@ -1005,10 +1027,10 @@ | |||
this.recordPath = item.recordPath; | |||
this.date = item.receptionTime; | |||
this.isshowFile = false; | |||
this.zyAudio() | |||
setTimeout(() => { | |||
this.$zaudio.operate(i) | |||
}, 50) | |||
this.getCorpusAnalysis() | |||
this.$forceUpdate() | |||
}, | |||
// 自动播放下一个文件 | |||
qeihuanwenjian() { | |||
@@ -1036,7 +1058,34 @@ | |||
asd.isshow = false; | |||
}) | |||
}) | |||
} | |||
}, | |||
//录音实例 | |||
zyAudio() { | |||
let data = this.luyinList.map((item, index) => { | |||
return { | |||
src: item.recordPath, | |||
title: `录音文件${index + 1}`, | |||
singer: '', | |||
coverImgUrl: '' | |||
} | |||
}) | |||
this.$zaudio.setAudio(data) | |||
//渲染第一首音频 | |||
this.$zaudio.setRender(0) | |||
setTimeout(() => { | |||
this.$zaudio.operate() | |||
}, 150) | |||
this.$forceUpdate() | |||
}, | |||
// 跳转指定位置播放 | |||
stepPlay(t) { | |||
this.$zaudio.seek(t) | |||
if (this.$zaudio.paused) { | |||
this.$zaudio.operate() | |||
} | |||
}, | |||
}, | |||
} | |||
</script> | |||
@@ -33,7 +33,7 @@ | |||
<view class="dialog-block" v-for="(dialog,i) in dialogList" :key="i"> | |||
<view :id="'dialog'+i" class="fileName">录音文件</view> | |||
<view class="text" :id="'dialog'+csdFileindex+'text'+item.bg" | |||
:class="{active: item.bg < playNow && item.ed > playNow && i==0}" | |||
:class="{active: Math.floor(item.bg/1000) <= playNow && Math.floor(item.ed/1000) > playNow && i==0, isGreen: item.isShow == 0}" | |||
v-for="(item,index) in dialog.message" :key="index" :data-speaker="item.speaker"> | |||
<view class="avatar"> | |||
<view :style="[SPEAKERSTYLE(item.speaker)]"> | |||
@@ -41,36 +41,42 @@ | |||
<text v-else>{{ item.speaker | toCapital }}</text> | |||
</view> | |||
</view> | |||
<view class="content"> | |||
<view @longpress="changanxiaoguo(item,index,i)" v-html="item.onebest"></view> | |||
<view class="tankuangcss" :class="{bottoms:index == 0}" v-if="item.isshow"> | |||
<view @click="clickcopy()" | |||
style="width: 60rpx;font-size: 24rpx;text-align: center;margin-left: 24rpx;">复制 | |||
</view> | |||
<view @click="Oftenthewrongword()" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 22rpx;">常错词 | |||
</view> | |||
<view v-if="jiaoseshow" @click="Addtheessence()" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 22rpx;">加精华 | |||
</view> | |||
<view @click="clickbofang(dialog.backindex,item)" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 14rpx;">播放 | |||
</view> | |||
<view @click="Modifyrole(index,item)" | |||
style="font-size: 24rpx;text-align: center;margin-left: 14rpx;">修改角色 | |||
<view class="contentInfo"> | |||
<view class="info"> | |||
<text class="AudioUserName">{{ item.speaker | toCapital }}</text> | |||
<text>{{conversionTiame(item.bg/1000)}}</text> | |||
</view> | |||
<view class="contentMain"> | |||
<view class="content"> | |||
<view @longpress="changanxiaoguo(item,index,i)" v-html="item.onebest"></view> | |||
<view class="tankuangcss" :class="{bottoms:index == 0}" v-if="item.isshow"> | |||
<view @click="clickcopy()" | |||
style="width: 60rpx;font-size: 24rpx;text-align: center;margin-left: 24rpx;">复制 | |||
</view> | |||
<view @click="Oftenthewrongword()" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 22rpx;">常错词 | |||
</view> | |||
<view v-if="jiaoseshow" @click="Addtheessence()" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 22rpx;">加精华 | |||
</view> | |||
<!-- <view @click="clickbofang(dialog.backindex,item)" | |||
style="width: 80rpx;font-size: 24rpx;text-align: center;margin-left: 14rpx;">播放 | |||
</view> --> | |||
<view @click="Modifyrole(index,item)" | |||
style="font-size: 24rpx;text-align: center;margin-left: 14rpx;">修改角色 | |||
</view> | |||
</view> | |||
</view> | |||
<image @click="clickbofang(dialog.backindex,item)" class="play" | |||
src="../../static/images/recordingManagement/play.png"></image> | |||
</view> | |||
</view> | |||
</view> | |||
</view> | |||
</scroll-view> | |||
<view class="bottombox"> | |||
<!-- <LongAudio :customerId="customerId" :infos="infos" :roleindex="roleindex"></LongAudio> --> | |||
<!-- 播放块 --> | |||
<!-- 播放块 :src="recordPath" --> | |||
<yz-audio ref="zyAudio" @timeUpdate="TimeUpdate" @sliderChangeComplate="sliderChangeComplate"></yz-audio> | |||
<zaudio :duration="duration" theme="theme4"></zaudio> | |||
<!-- 底部弹框 --> | |||
<view class="botbotmm"> | |||
<view class="tmmchen" @click="guanjiancishifo()"> | |||
@@ -407,11 +413,13 @@ | |||
<script> | |||
var util = require("../../utils/util.js"); | |||
var config = require("../../config"); | |||
import LongAudio from "@/components/long_audio/long_audio.vue" | |||
import zaudio from '@/components/uniapp-zaudio/zaudio'; | |||
export default { | |||
components: { | |||
LongAudio | |||
zaudio | |||
}, | |||
data() { | |||
return { | |||
noClick: true, | |||
@@ -427,7 +435,6 @@ | |||
audioPlay: false, //当前的播放状态控制 | |||
sliderValue: 0, //进度条最小值 | |||
sliderMax: 0, //进度条最大值 | |||
innerAudioContext: "", //播放实例 | |||
currentTimeStr: "00:00", //当前进度的时间 | |||
timeStr: "00:00", //总的时间 | |||
recordPath: "", | |||
@@ -510,23 +517,55 @@ | |||
roleisshaw: false, | |||
roleindexrow: 0, | |||
roletiaoshu: 0, | |||
infos: null | |||
infos: null, | |||
ACTION: Symbol('zaudio'), // 唯一值区分每个页面的方法 | |||
isPageHide: false, // 是否息屏 | |||
duration: '', // 总时长 | |||
}; | |||
}, | |||
onLoad: function(options) { | |||
computed: { | |||
conversionTiame() { | |||
return (e) => { | |||
return this.getTime(e); | |||
} | |||
}, | |||
}, | |||
onLoad(options) { | |||
this.status = options.status; | |||
this.customerId = options.customerId; | |||
this.itemobj = uni.getStorageSync('searchobj'); | |||
console.log(this.itemobj) | |||
this.stateisshow = options.stateisshow; | |||
uni.$on("playNows", (val) => { | |||
this.playNow = val; | |||
this.$zaudio.autoPlay = true | |||
//注意: 不同的回调方法, 相同的业务函数方法名, 不会相互影响; | |||
this.$zaudio.on('stop', this.ACTION, () => { | |||
console.log('我是强制暂停或关闭小程序音频浮窗触发的') | |||
}) | |||
this.$zaudio.on('seek', this.ACTION, (time) => { | |||
this.sliderChangeComplate(this.TIMEEVENT(time)) | |||
}) | |||
this.$zaudio.on('playing', this.ACTION, (obj) => { | |||
this.duration = obj.duration | |||
console.log(obj) | |||
this.TimeUpdate(this.TIMEEVENT(obj.current)) | |||
}) | |||
uni.$on("scrollIds", (val) => { | |||
this.scrollId = val; | |||
this.$zaudio.on('error', this.ACTION, e => { | |||
console.log(e, '加载失败') | |||
}) | |||
this.$zaudio.on('ended', this.ACTION, e => { | |||
this.$zaudio.stop() | |||
this.init({bg: 0, customerId: this.customerId}) | |||
}) | |||
uni.$on('DETAILS2INIT', (info) => { | |||
this.init(info) | |||
}); | |||
}, | |||
onShow() { | |||
//实时渲染当前的播放状态 | |||
this.$zaudio.syncRender() | |||
this.Menulist = uni.getStorageSync('weapp_session_Menu_data'); | |||
this.Menulist.forEach(item => { | |||
if (item.name == '标记有效无效接待') { | |||
@@ -548,16 +587,24 @@ | |||
this.roleindex = 0; | |||
if (this.stateisshow == 2) { | |||
this.infos = this.itemobj; | |||
} else { | |||
var pages = getCurrentPages(); | |||
var currPage = pages[pages.length - 1]; //当前页面 | |||
this.infos = currPage.data.info; | |||
} | |||
this.gituserlist() | |||
this.init(this.infos) | |||
!this.isPageHide && this.init(this.infos); | |||
}, | |||
onHide() { | |||
this.isPageHide = true | |||
}, | |||
onUnload() { | |||
uni.$off('DETAILS2INIT') | |||
//卸载不需要的业务和获取播放状态的业务,提高页面性能 | |||
this.$zaudio.off('seek', this.ACTION); | |||
this.$zaudio.off('stop', this.ACTION); | |||
this.$zaudio.off('playing', this.ACTION); | |||
}, | |||
methods: { | |||
rolexuanze(index) { | |||
this.roleindexrow = index; | |||
@@ -588,7 +635,6 @@ | |||
title: '修改成功', | |||
duration: 2000 | |||
}); | |||
}) | |||
}, | |||
argece(item) { | |||
@@ -606,7 +652,7 @@ | |||
//进搜索页面 | |||
uni.navigateTo({ | |||
url: '/pages/learning/Keywordsearch?customerId=' + this.customerId + "&keyword=" + item + | |||
"&skpl=" + "2" | |||
"&skpl=" + "2" + '&UpDateEvent=DETAILS2INIT' | |||
}) | |||
}, | |||
recordclick(i) { | |||
@@ -861,7 +907,7 @@ | |||
this.stateisshow = 1; | |||
uni.navigateTo({ | |||
url: '/pages/learning/Keywordsearch?customerId=' + this.customerId + "&status=" + this.status + | |||
"&skpl=" + "1" | |||
"&skpl=" + "1" + '&UpDateEvent=DETAILS2INIT' | |||
}) | |||
}, | |||
@@ -926,7 +972,7 @@ | |||
}, | |||
//分角色标记刷新 | |||
fenjiaoseunfo() { | |||
var bgcd = this.sliderValue * 1000; | |||
var bgcd = this.playNow * 1000; | |||
this.newluyinList = []; | |||
this.dialogList = []; | |||
uni.request({ | |||
@@ -989,26 +1035,28 @@ | |||
}) | |||
}, | |||
toKeywordsearch() { | |||
this.stateisshow = 1; | |||
uni.navigateTo({ | |||
url: '/pages/learning/Keywordsearch?customerId=' + this.customerId + "&status=" + this.status + | |||
"&skpl=" + "1" | |||
"&skpl=" + "1" + '&UpDateEvent=DETAILS2INIT' | |||
}) | |||
}, | |||
TimeUpdate(e) { | |||
const { | |||
currentTime, | |||
duration | |||
} = e | |||
this.playNow = parseInt(currentTime * 1000) | |||
TimeUpdate(currentTime) { | |||
this.playNow = Math.ceil(currentTime) | |||
if (this.dialogList.length == 0) { | |||
return | |||
} else { | |||
const message = this.dialogList[0].message; | |||
if (!message) return | |||
for (let i = 0; i < message.length; i++) { | |||
if (Number(message[i].bg) < this.playNow && Number(message[i].ed) > this.playNow) { | |||
if (Math.floor(message[i].bg/1000) <= this.playNow && this.playNow < Math.floor(message[i].ed/1000)) { | |||
console.log(message[i].bg, '我是active', message[i].ed, '我是currentTime', this.playNow) | |||
console.log(message[i].onebest) | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
if (i < message.length - 1 && Math.floor(message[i].ed/1000) < this.playNow && this.playNow < Math.floor(message[i + 1].bg/1000)) { | |||
this.scrollId = "dialog" + this.csdFileindex + "text" + message[i].bg; | |||
break; | |||
} | |||
@@ -1048,20 +1096,15 @@ | |||
this.recordPath = res[0].recordPath | |||
this.date = res[0].receptionTime; | |||
this.getCorpusAnalysis(info); | |||
this.zyAudio() | |||
} | |||
this.zyAudio() | |||
} | |||
}) | |||
}, | |||
//搜索跳转 | |||
adasdasdasd(e) { | |||
this.$refs.zyAudio.seek(e) | |||
if (uni.getStorageSync('entrance') == 1) { | |||
return | |||
} else { | |||
this.$refs.zyAudio.play(); | |||
} | |||
this.stepPlay(e) | |||
}, | |||
//下一页 | |||
ltolower() { | |||
@@ -1100,7 +1143,6 @@ | |||
}) | |||
} | |||
} | |||
console.log("上一页", this.toptextindex) | |||
}, | |||
// 取消全部加精 | |||
notappick() { | |||
@@ -1276,13 +1318,6 @@ | |||
id: 0 | |||
}) | |||
}) | |||
// util.getRequestPromise(config.service.findAllYi, {"itemId":this.buildingID}, false).then(data => { | |||
// this.biaoqianlist = data | |||
// this.biaoqianlist.unshift({ | |||
// name: "逼单话术", | |||
// id: 0 | |||
// }) | |||
// }); | |||
}, | |||
// 取消加精 | |||
Cancelout2() { | |||
@@ -1529,13 +1564,8 @@ | |||
//音频前进回退 | |||
sliderChangeComplate(e) { | |||
if (e.isType == 'audio') { | |||
this.$refs.zyAudio.pause() | |||
} else { | |||
this.$refs.zyAudio.audioPause() | |||
} | |||
let platetime = e.detail.value * 1000; | |||
sliderChangeComplate(currentTime) { | |||
let platetime = (currentTime * 1000) || 0; | |||
this.dialogList = [] | |||
uni.request({ | |||
url: config.service.fastForward + '?corpusId=' + this.luyinList[this.csdFileindex].id + | |||
@@ -1553,20 +1583,11 @@ | |||
} else { | |||
this.dialogList.push(this.newluyinList[data.data.data.index]) | |||
} | |||
if (e.isType == 'audio') { | |||
this.$refs.zyAudio.seek(e.detail.value); | |||
this.$refs.zyAudio.play(); | |||
} else { | |||
this.$refs.zyAudio.audioSeek(e.detail.value); | |||
this.$refs.zyAudio.audioPlay(); | |||
} | |||
} | |||
}) | |||
}, | |||
//长按点击播放 | |||
clickbofang(dialog, item) { | |||
this.innerAudioContext.pause() | |||
this.dialogList.forEach(res => { | |||
res.message.forEach(asd => { | |||
asd.isshow = false; | |||
@@ -1575,11 +1596,10 @@ | |||
this.$forceUpdate() | |||
let platetime = item.bg; | |||
let newtime = item.bg / 1000; | |||
console.log(newtime, 'newTime') | |||
this.dialogList = [] | |||
uni.request({ | |||
url: config.service.fastForward + '?corpusId=' + this.luyinList[this.csdFileindex].id + | |||
"&bg=" + platetime, //仅为示例,并非真实接口地址。 | |||
"&bg=" + platetime || 0, //仅为示例,并非真实接口地址。 | |||
method: "GET", | |||
header: { | |||
'content-type': 'application/json', | |||
@@ -1589,9 +1609,8 @@ | |||
this.textindex = data.data.data.index; | |||
this.toptextindex = data.data.data.index; | |||
this.dialogList.push(this.newluyinList[data.data.data.index]) | |||
this.currentTimeStr = currTimeStr | |||
this.$refs.zyAudio.seek(newtime) | |||
this.$refs.zyAudio.play() | |||
console.log(newtime) | |||
this.stepPlay(newtime); | |||
} | |||
}) | |||
}, | |||
@@ -1610,10 +1629,31 @@ | |||
}) | |||
}, | |||
//录音实例 | |||
zyAudio() { | |||
this.$refs.zyAudio.setSrc(this.recordPath) | |||
let data = [{ | |||
src: this.recordPath, | |||
title: '录音音频', | |||
singer: '', | |||
coverImgUrl: '' | |||
}] | |||
this.$zaudio.setAudio(data) | |||
//渲染第一首音频 | |||
this.$zaudio.setRender(0) | |||
setTimeout(() => { | |||
this.$zaudio.operate() | |||
}, 150) | |||
}, | |||
// 跳转指定位置播放 | |||
stepPlay(t) { | |||
this.$zaudio.seek(t) | |||
if (this.$zaudio.paused) { | |||
this.$zaudio.operate() | |||
} | |||
} | |||
}, | |||
} | |||
</script> | |||
@@ -1808,6 +1848,7 @@ | |||
font-size: 26rpx; | |||
color: #333333; | |||
text-align: center; | |||
box-shadow: 10rpx 10rpx 5rpx #888888; | |||
} | |||
} | |||
@@ -2132,42 +2173,97 @@ | |||
flex-direction: row-reverse; | |||
text-align: right; | |||
.content { | |||
margin-left: 0; | |||
margin-right: 30upx; | |||
background: #F6F6F6; | |||
color: #999999; | |||
.contentInfo { | |||
.info { | |||
color: #ccc; | |||
font-size: 18rpx; | |||
font-size: 30rpx; | |||
padding: 0 28rpx; | |||
} | |||
.contentMain { | |||
display: flex; | |||
flex-direction: row-reverse; | |||
align-items: center; | |||
.content { | |||
margin-left: 0; | |||
margin-right: 30upx; | |||
} | |||
.play { | |||
width: 50rpx; | |||
height: 50rpx; | |||
margin-right: 20rpx; | |||
} | |||
} | |||
} | |||
} | |||
.scroll-Y .text[data-speaker="2"], | |||
.scroll-Y .text[data-speaker="4"], | |||
.scroll-Y .text[data-speaker="6"] { | |||
.contentInfo { | |||
.info { | |||
.AudioUserName { | |||
margin-left: 10rpx; | |||
} | |||
display: flex; | |||
flex-direction: row-reverse; | |||
} | |||
} | |||
} | |||
.scroll-Y .text { | |||
.contentInfo { | |||
.info { | |||
.AudioUserName { | |||
margin-right: 10rpx; | |||
} | |||
} | |||
} | |||
} | |||
.scroll-Y .text .avatar { | |||
margin-top: 80rpx; | |||
width: 64upx; | |||
height: 64upx; | |||
line-height: 64upx; | |||
text-align: center; | |||
// border: 1rpx solid red; | |||
font-size: 36rpx; | |||
border-radius: 50%; | |||
background: #F2F2F2; | |||
color: #008EF2; | |||
// display: flex; | |||
// justify-content: center; | |||
// align-items: center; | |||
image { | |||
width: 40upx; | |||
} | |||
} | |||
.scroll-Y .text .contentInfo .info { | |||
color: #ccc; | |||
font-size: 18rpx; | |||
font-size: 30rpx; | |||
padding: 0 28rpx; | |||
} | |||
.scroll-Y .text .contentInfo .contentMain { | |||
display: flex; | |||
align-items: center; | |||
} | |||
.scroll-Y .text .content { | |||
.scroll-Y .text .contentInfo .contentMain .content { | |||
margin-left: 30upx; | |||
line-height: 60rpx; | |||
text-align: left; | |||
padding: 0 5px; | |||
background: #2BC805; | |||
border-radius: 8upx; | |||
max-width: 442rpx; | |||
color: #FFFFFF; | |||
background: #F6F6F6; | |||
color: #999999; | |||
position: relative; | |||
.tankuangcss { | |||
@@ -2193,16 +2289,10 @@ | |||
} | |||
} | |||
.scroll-Y .text.active .content { | |||
color: #38FFF1; | |||
position: relative; | |||
} | |||
.scroll-Y .text.active[data-speaker="2"] .content, | |||
.scroll-Y .text.active[data-speaker="4"] .content, | |||
.scroll-Y .text.active[data-speaker="6"] .content { | |||
color: #FF7538; | |||
position: relative; | |||
.scroll-Y .text .contentInfo .contentMain .play { | |||
width: 50rpx; | |||
height: 50rpx; | |||
margin-left: 20rpx; | |||
} | |||
.backTop { | |||
@@ -2225,8 +2315,8 @@ | |||
} | |||
.jiangshang { | |||
color: #2671E2; | |||
background: #F4F8FD; | |||
color: #fff; | |||
background: #2671E2; | |||
} | |||
.jiangshang1 { | |||
@@ -2474,4 +2564,23 @@ | |||
padding: 20rpx; | |||
border: 1rpx solid #E4F0FF; | |||
} | |||
.scroll-Y .text.active .content { | |||
color: #FF7538 !important; | |||
position: relative; | |||
} | |||
.scroll-Y .text.active[data-speaker] .content, | |||
.scroll-Y .text.active[data-speaker="2"] .content, | |||
.scroll-Y .text.active[data-speaker="4"] .content, | |||
.scroll-Y .text.active[data-speaker="6"] .content { | |||
color: #FF7538 !important; | |||
position: relative; | |||
} | |||
.scroll-Y .isGreen .contentInfo .contentMain .content { | |||
background: #2BC805 !important; | |||
color: #FFFFFF; | |||
} | |||
</style> |
@@ -6,8 +6,8 @@ | |||
// const baseUrl = 'http://192.168.31.167:8080/autoSR/api'; // 长龙 | |||
// const baseUrl = 'http://192.168.31.134:8080/autoSR/api'; // 佳豪 | |||
// const baseUrl = 'http://10.2.1.104:8081/autoSR/api'; // 刘敏 | |||
const baseUrl = 'https://zkgj.quhouse.com/api'; // 质控正式 | |||
// const baseUrl = 'https://hfju.com/api'; // 数智正式 | |||
// const baseUrl = 'https://zkgj.quhouse.com/api'; // 质控正式 | |||
const baseUrl = 'https://hfju.com/api'; // 数智正式 | |||
// config使用域名 | |||