123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967 |
- <template>
- <div class="o_box" ref="obox">
- <div class="o_top">
- </div>
- <div class="o_content">
- <div class="type_box" :style="{ width: oWidth }" v-if="cjson.type !== 'createRole'">
- {{ getType(cjson) }}
- </div>
- <div class="word_box" v-if="cjson.type == 'word' || cjson.type == 'QA'" ref="wb">
- <div class="word_bbox" :style="{ maxHeight: oheight }">
- <img class="word_img" :src="cjson.img" alt="" v-if="cjson.img" @click="previewImg(cjson.img)">
- <div class="word_content" v-html="cjson.content">
- </div>
- </div>
- </div>
- <div class="sentence_box" v-if="cjson.type == 'sentence'" ref="wb">
- <span v-html="cjson.content"></span>
- <div v-if="cjson.img" class="sentence_div">
- <img :src="cjson.img" alt="" @click="previewImg(cjson.img)">
- </div>
- </div>
- <div class="word_box" v-if="cjson.type == 'theme'" ref="wb" style="max-height: calc(100% - 95px);">
- <div class="word_bbox" :style="{ maxHeight: oheight }">
- <div class="word_content" v-html="cjson.content"></div>
- <div class="word_content2" v-html="cjson.content2" v-if="cjson.content2"></div>
- </div>
- </div>
- <div class="tips_box" v-if="cjson.type == 'theme' && !isRecord && !LuAudioUrl">提示:准备完成后,点击话筒开始录音</div>
- <div class="time_box" v-if="cjson.type == 'theme' && isRecord">
- <span>倒计时</span>
- <span>{{ Times.min }}:{{ Times.secode }}</span>
- </div>
- <testRole v-if="cjson.type == 'createRole'" :checkJson="answerArray"></testRole>
- </div>
- <div class="o_bottom" v-loading="isloading">
- <div class="star_box" v-if="LuAudioUrl && star > 0">
- <div class="star" v-for="index2 in 5" :key="'star' + index2" :class="{ starA: star >= (index2) }">
- </div>
- </div>
- <div class="audio" v-if="!LuAudioUrl">
- <img v-if="!isRecord" src="../../../assets/icon/englishVoice/start_aduio.png" alt="" @click="startRecorder">
- <img v-else src="../../../assets/icon/englishVoice/stop_audio.png" alt="" @click="startRecorder">
- </div>
- <div class="audio_word" v-if="!LuAudioUrl">
- <span v-if="!isRecord">点击话筒开始录音</span>
- <span v-else>点击话筒结束录音</span>
- </div>
- <div v-if="LuAudioUrl" class="audio_b">
- <mini-audio :audio-source="LuAudioUrl" class="audio_class"></mini-audio>
- </div>
- <div v-if="LuAudioUrl" class="audio_rerecord" @click="restart()">
- <span>录音</span>
- </div>
- <div class="audio_index" v-if="!isRecord">
- <div class="audio_index_last" :class="{ disabled: checkType == 0 }" @click="checkIndex('-1')">
- <img src="../../../assets/icon/englishVoice/coin.png" alt="">
- </div>
- <div class="audio_index_content">
- <span>{{ checkType + 1 }}</span>
- <span>/</span>
- <span>{{ checkJson.length }}</span>
- </div>
- <div class="audio_index_next" :class="{ disabled: checkType == (checkJson.length - 1) }" @click="checkIndex('1')">
- <img src="../../../assets/icon/englishVoice/coin.png" alt="">
- </div>
- </div>
- <div v-else class="audio_ing">
- <span>正在录音...</span>
- </div>
- </div>
- <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;"
- src="https://beta.cloud.cocorobo.cn/browser/public/index.html" ref="iiframe" v-show="false"></iframe>
- </div>
- </template>
- <script>
- import Recorder from "js-audio-recorder";
- const lamejs = require("lamejs");
- const recorder = new Recorder({
- sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
- sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
- numChannels: 1, // 声道,支持 1 或 2, 默认是1
- // compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
- });
- // 绑定事件-打印的是当前录音数据
- recorder.onprogress = function (params) {
- // console.log('--------------START---------------')
- // console.log('录音时长(秒)', params.duration);
- // console.log('录音大小(字节)', params.fileSize);
- // console.log('录音音量百分比(%)', params.vol);
- // console.log('当前录音的总数据([DataView, DataView...])', params.data);
- // console.log('--------------END---------------')
- };
- import testRole from "./testRole.vue";
- export default {
- components: {
- testRole,
- },
- props: {
- checkJson: {
- type: Array,
- },
- checkType: {
- type: Number,
- },
- work: {
- type: Array
- }
- },
- data() {
- return {
- cjson: {},
- LuAudioUrl: "",
- isRecord: false,
- isPlayerRecord: false,
- isloading: false,
- oheight: 'auto',
- oWidth: '500px',
- calcTimer: null,
- totalSeconds: 0,
- answerArray: [],
- id: this.guid(),
- star: 0
- }
- },
- computed: {
- // oheight: function() {
- // // 获取父元素
- // var parentElement = this.$refs['wb'];
- // // 计算父元素的高度
- // var parentHeight = parentElement.offsetHeight;
- // return parentHeight + 'px'
- // }
- getType() {
- return function (json) {
- if (json.type == 'word') {
- return '单词/词组'
- } else if (json.type == 'QA') {
- return '问答题目'
- } else if (json.type == 'sentence') {
- return '句子/短文'
- } else if (json.type == 'theme') {
- return '主题陈述'
- }
- };
- },
- Times() {
- let min = this.totalSeconds ? Math.floor(this.totalSeconds / 60) : 0
- let secode = this.totalSeconds ? this.totalSeconds % 60 : 0
- let time = {
- min: min >= 10 ? min : '0' + min,
- secode: secode >= 10 ? secode : '0' + secode
- }
- return time;
- },
- },
- watch: {
- checkType: {
- handler: function (newVal, oldVal) {
- this.isloading = false
- this.cjson = JSON.parse(JSON.stringify(this.checkJson[newVal]));
- this.LuAudioUrl = ''
- if (typeof this.work[newVal] == 'string') {
- this.LuAudioUrl = this.work[newVal] ? JSON.parse(JSON.stringify(this.work[newVal])) : ''
- } else if (typeof this.work[newVal] == 'object' && this.cjson.type != 'createRole') {
- this.LuAudioUrl = this.work[newVal].audio ? JSON.parse(JSON.stringify(this.work[newVal].audio)) : ''
- } else if (typeof this.work[newVal] == 'object' && this.cjson.type == 'createRole') {
- var a = Array.isArray(this.work[newVal])
- if (a) {
- this.answerArray = JSON.parse(JSON.stringify(this.work[newVal]))
- } else {
- this.answerArray = []
- this.answerArray.push(
- {
- isY: false,
- content: this.cjson.content3,
- name: this.cjson.content,
- img: this.cjson.img
- }
- )
- }
- this.$emit('setWork', this.answerArray, this.checkType)
- }
- if (!this.work[newVal] && this.cjson.type == 'createRole') {
- var a = Array.isArray(this.work[newVal])
- if (a) {
- this.answerArray = JSON.parse(JSON.stringify(this.work[newVal]))
- } else {
- this.answerArray = []
- this.answerArray.push(
- {
- isY: false,
- content: this.cjson.content3,
- name: this.cjson.content,
- img: this.cjson.img
- }
- )
- }
- this.$emit('setWork', this.answerArray, this.checkType)
- }
- this.star = this.work[newVal] ? (this.work[newVal].score ? JSON.parse(JSON.stringify(this.work[newVal].score)) : 0) : 0
- this.oheight = 'auto'
- this.oWidth = '500px'
- const images = this.$refs['obox'].querySelectorAll('img');
- let loadedCount = 0;
- // if(images.length){
- // images.forEach((image) => {
- // image.addEventListener('load', () => {
- // loadedCount++;
- // if (loadedCount === images.length) {
- // this.calculateParentHeight()
- // }
- // });
- // });
- // }else{
- if (this.cjson.type != "createRole") {
- this.calculateParentHeight()
- }
- if (this.cjson.type == "createRole") {
- this.createRole(this.cjson.content2, this.cjson.content)
- }
- // }
- },
- deep: true,
- },
- },
- methods: {
- previewImg(url) {
- this.$hevueImgPreview(url);
- },
- restart() {
- let _this = this
- _this.$confirm("确定重新录音么?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- _this.LuAudioUrl = ""
- setTimeout(() => {
- _this.startRecorder()
- }, 500);
- })
- .catch(() => { });
- },
- checkIndex(type) {
- if (type == '1') {
- if (this.checkType == (this.checkJson.length - 1)) {
- return;
- }
- this.$emit('setType', this.checkType + 1)
- } else {
- if (this.checkType == 0) {
- return;
- }
- this.$emit('setType', this.checkType - 1)
- }
- },
- // 开始录音
- startRecorder() {
- let _this = this;
- if (!_this.isRecord) {
- recorder.destroy(); // 销毁录音
- _this.isRecord = true;
- if (this.cjson.type == 'theme') {
- this.setSecodes()
- }
- recorder.start().then(
- () => { },
- (error) => {
- _this.isRecord = false;
- // _this.$message.error(`${error.name} : ${error.message}`);
- _this.$message.error(`没有找到可使用的麦克风,或者您没有允许此网页使用麦克风`);
- // 出错了
- console.log(`${error.name} : ${error.message}`);
- if (_this.calcTimer) {
- clearInterval(_this.calcTimer)
- _this.calcTimer = null;
- }
- }
- );
- } else {
- if (_this.calcTimer) {
- clearInterval(_this.calcTimer)
- _this.calcTimer = null;
- }
- _this.isRecord = false;
- recorder.stop(); // 结束录音
- this.getMp3Data()
- }
- },
- // 录音播放
- playRecorder() {
- if (!recorder.fileSize) {
- return;
- }
- if (!this.isPlayerRecord) {
- this.isPlayerRecord = true;
- recorder.play();
- } else {
- this.isPlayerRecord = false;
- recorder.stopPlay(); // 停止录音播放
- }
- recorder.onplayend = () => {
- this.isPlayerRecord = false;
- console.log("onplayend");
- };
- },
- /**
- * 文件格式转换 wav-map3
- * */
- getMp3Data() {
- if (!recorder.fileSize) {
- this.$message.error("请录音后在上传语音");
- return;
- }
- const mp3Blob = recorder.getWAVBlob();
- // const mp3Blob = this.convertToMp3(recorder.getWAV());
- let audioFile = this.dataURLtoAudio(mp3Blob, "wav");
- console.log(audioFile);
- let iiframe = this.$refs['iiframe']
- // this.isloading = true
- // this.beforeUpload1(audioFile, 3);
- // return;
- if (this.cjson.type == 'theme' || this.cjson.type == 'QA') {
- this.isloading = true
- let _this = this
- iiframe.contentWindow.onRecognizedResult = function (e) {
- console.log('onRecognizedResult', e);
- let privText = e.privText
- _this.beforeUpload1(audioFile, 3, privText);
- }
- iiframe.contentWindow.doContinuousPronunciationAssessment('', { files: [audioFile] })
- } else if (this.cjson.type == 'createRole') {
- // this.isloading = true
- // this.beforeUpload1(audioFile, 3);
- this.isloading = true
- let _this = this
- iiframe.contentWindow.onRecognizedResult = function (e) {
- console.log('onRecognizedResult', e);
- let privText = e.privText
- _this.beforeUpload1(audioFile, 3, privText);
- }
- iiframe.contentWindow.doContinuousPronunciationAssessment('', { files: [audioFile] })
- } else {
- this.isloading = true
- let _this = this
- iiframe.contentWindow.onRecognizedResult = function (e) {
- console.log('onRecognizedResult', e);
- let privText = e.privText
- let star = JSON.parse(e.privJson).NBest[0].PronunciationAssessment
- console.log('star', star)
- // e.privText
- // JSON.parse(e.privJson).NBest[0].PronunciationAssessment
- _this.beforeUpload1(audioFile, 3, privText, star);
- }
- iiframe.contentWindow.doContinuousPronunciationAssessment(this.cjson.content, { files: [audioFile] })
- }
- // recorder.download(mp3Blob, "recorder", "mp3");
- },
- convertToMp3(wavDataView) {
- // 获取wav头信息
- const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置
- const { channels, sampleRate } = wav;
- const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
- // 获取左右通道数据
- const result = recorder.getChannelData();
- const buffer = [];
- const leftData =
- result.left &&
- new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
- const rightData =
- result.right &&
- new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
- const remaining = leftData.length + (rightData ? rightData.length : 0);
- const maxSamples = 1152;
- for (let i = 0; i < remaining; i += maxSamples) {
- const left = leftData.subarray(i, i + maxSamples);
- let right = null;
- let mp3buf = null;
- if (channels === 2) {
- right = rightData.subarray(i, i + maxSamples);
- mp3buf = mp3enc.encodeBuffer(left, right);
- } else {
- mp3buf = mp3enc.encodeBuffer(left);
- }
- if (mp3buf.length > 0) {
- buffer.push(mp3buf);
- }
- }
- const enc = mp3enc.flush();
- if (enc.length > 0) {
- buffer.push(enc);
- }
- return new Blob(buffer, { type: "audio/wav" });
- },
- dataURLtoAudio(blob, filename) {
- return new File([blob], filename, { type: "audio/wav" });
- },
- beforeUpload1(event, type, text, star) {
- var file;
- if (type == 3) {
- file = event;
- } else {
- file = event.target.files[0];
- }
- var credentials = {
- accessKeyId: "AKIATLPEDU37QV5CHLMH",
- secretAccessKey: "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",
- }; //秘钥形式的登录上传
- window.AWS.config.update(credentials);
- window.AWS.config.region = "cn-northwest-1"; //设置区域
- var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
- var _this = this;
- if (file) {
- var params = {
- Key:
- file.name.split(".")[0] +
- new Date().getTime() +
- "." +
- file.name.split(".")[file.name.split(".").length - 1],
- ContentType: file.type,
- Body: file,
- "Access-Control-Allow-Credentials": "*",
- ACL: "public-read",
- }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
- var options = {
- partSize: 2048 * 1024 * 1024,
- queueSize: 2,
- leavePartsOnError: true,
- };
- bucket
- .upload(params, options)
- .on("httpUploadProgress", function (evt) {
- //这里可以写进度条
- // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
- // _this.progress = parseInt((evt.loaded * 80) / evt.total);
- })
- .send(function (err, data) {
- if (_this.cjson.type != 'createRole') {
- _this.isloading = false
- }
- // _this.progress = 100;
- if (err) {
- var a = _this.$refs.upload1.uploadFiles;
- a.splice(a.length - 1, a.length);
- _this.$message.error("上传失败");
- } else {
- if (type == 3) {
- if (_this.cjson.type == 'createRole') {
- _this.answerArray.push(
- {
- isY: true,
- content: text,
- voice: data.Location,
- name: '',
- img: ''
- }
- )
- _this.answerCode(text)
- } else {
- _this.LuAudioUrl = data.Location;
- _this.$emit('setWork', _this.LuAudioUrl, _this.checkType, text, star)
- }
- }
- console.log(data.Location);
- }
- });
- }
- },
- calculateParentHeight() {
- this.$nextTick(() => {
- setTimeout(() => {
- // 获取父元素
- var parentElement = this.$refs['wb'];
- // 计算父元素的高度
- // var parentHeight = parentElement.offsetHeight + 1;
- var parentWidth = parentElement.offsetWidth;
- // this.oheight = parentHeight + 'px'
- this.oWidth = parentWidth + 'px'
- }, 50);
- });
- },
- setSecodes() {
- this.totalSeconds = this.checkJson[this.checkType].oTime * 60
- // this.totalSeconds = 10
- this.calcTimer = setInterval(() => {
- if (this.totalSeconds > 0) {
- this.totalSeconds--;
- } else {
- clearInterval(this.calcTimer);
- this.calcTimer = null
- this.startRecorder()
- console.log("倒计时结束"); // 输出日志
- }
- }, 1000);
- },
- answerCode(msg) {
- var _this = this;
- _this.ajax.post('https://gpt4.cocorobo.cn/assistants_completion_response', {
- uid: _this.id,
- message: msg,
- }).then(function (response) {
- console.log(response);
- _this.answerArray.push(
- {
- isY: false,
- content: response.data.FunctionResponse,
- name: _this.answerArray[0].name,
- img: _this.answerArray[0].img
- }
- )
- console.log(_this.answerArray);
- _this.$forceUpdate()
- _this.isloading = false
- _this.$emit('setWork', _this.answerArray, _this.checkType)
- }).catch(function (error) {
- _this.isloading = false
- console.log(error);
- });
- },
- guid() {
- var _num,
- i,
- _guid = "";
- for (i = 0; i < 32; i++) {
- _guid += Math.floor(Math.random() * 16).toString(16); //随机0 - 16 的数字 转变为16进制的字符串
- _num = Math.floor((i - 7) / 4); //计算 (i-7)除4
- if (_num > -1 && _num < 4 && i == 7 + 4 * _num) {
- //会使guid中间加 "-" 形式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- _guid += "-";
- }
- }
- return _guid;
- },
- createRole(content, name) {
- var _this = this;
- _this.ajax.post('https://gpt4.cocorobo.cn/create_free_assistants', {
- fileName: [],
- url: [],
- uid: _this.id,
- instructions: content,
- assistantName: name
- }).then(function (response) {
- console.log(response);
- }).catch(function (error) {
- console.log(error);
- });
- }
- },
- beforeDestroy() {
- if (!this.isRecord) {
- } else {
- if (this.calcTimer) {
- clearInterval(this.calcTimer)
- this.calcTimer = null;
- }
- recorder.stop(); // 结束录音
- }
- },
- mounted() {
- this.cjson = JSON.parse(JSON.stringify(this.checkJson[this.checkType]));
- this.LuAudioUrl = ''
- if (typeof this.work[this.checkType] == 'string') {
- this.LuAudioUrl = this.work[this.checkType] ? JSON.parse(JSON.stringify(this.work[this.checkType])) : ''
- } else if (typeof this.work[this.checkType] == 'object' && this.cjson.type != 'createRole') {
- this.LuAudioUrl = this.work[this.checkType].audio ? JSON.parse(JSON.stringify(this.work[this.checkType].audio)) : ''
- } else if (typeof this.work[this.checkType] == 'object' && this.cjson.type == 'createRole') {
- var a = Array.isArray(this.work[this.checkType])
- if (a) {
- this.answerArray = JSON.parse(JSON.stringify(this.work[this.checkType]))
- } else {
- this.answerArray = []
- this.answerArray.push(
- {
- isY: false,
- content: this.cjson.content3,
- name: this.cjson.content,
- img: this.cjson.img
- }
- )
- }
- this.$emit('setWork', this.answerArray, this.checkType)
- }
- if (!this.work[this.checkType] && this.cjson.type == 'createRole') {
- var a = Array.isArray(this.work[this.checkType])
- if (a) {
- this.answerArray = JSON.parse(JSON.stringify(this.work[this.checkType]))
- } else {
- this.answerArray = []
- this.answerArray.push(
- {
- isY: false,
- content: this.cjson.content3,
- name: this.cjson.content,
- img: this.cjson.img
- }
- )
- }
- this.$emit('setWork', this.answerArray, this.checkType)
- }
- this.star = this.work[this.checkType] ? (this.work[this.checkType].score ? JSON.parse(JSON.stringify(this.work[this.checkType].score)) : 0) : 0
- if (this.cjson.type != "createRole") {
- this.calculateParentHeight()
- }
- if (this.cjson.type == "createRole") {
- this.createRole(this.cjson.content2, this.cjson.content)
- }
- },
- }
- </script>
- <style scoped>
- .o_box {
- width: 100%;
- height: 100%;
- background-image: url('../../../assets/icon/env_background.png');
- background-size: cover;
- }
- .o_top {
- height: 65px;
- position: absolute;
- }
- .o_content {
- height: calc(100% - 210px);
- display: flex;
- align-items: center;
- justify-content: center;
- overflow: hidden;
- flex-direction: column;
- }
- .o_bottom {
- height: 210px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .word_box {
- min-width: 500px;
- max-width: 70%;
- background: #fff;
- border-radius: 10px;
- position: relative;
- /* max-height: calc(100% - 40px); */
- max-height: calc(100% - 70px);
- /* overflow: auto; */
- }
- .tips_box {
- margin-top: 30px;
- color: #727272;
- }
- .word_box>.word_bbox {
- width: 100%;
- position: relative;
- z-index: 999;
- max-height: 100%;
- overflow: auto;
- }
- .sentence_box {
- background: #e0e0e04d;
- min-width: 500px;
- max-width: 70%;
- border-radius: 15px;
- /* max-height: 100%; */
- overflow: auto;
- padding: 15px;
- font-size: 16px;
- color: #000;
- line-height: 20px;
- word-break: break-word;
- white-space: pre-line;
- max-height: calc(100% - 80px);
- }
- .word_box::before {
- content: '';
- position: absolute;
- width: 100%;
- height: 100%;
- display: block;
- box-shadow: 0 0 4px 4px #1d39830d;
- border-radius: 10px;
- z-index: 2;
- background: #fff;
- }
- .word_box::after {
- content: '';
- position: absolute;
- width: 100%;
- height: 100%;
- background: #fff;
- display: block;
- box-shadow: 0 0 4px 4px #1d39830d;
- border-radius: 10px;
- z-index: 1;
- top: 15px;
- left: 15px;
- }
- .word_box>.word_bbox>.word_img {
- width: calc(100% - 30px);
- max-height: 300px;
- z-index: 999;
- position: relative;
- margin: 15px auto;
- display: block;
- border-radius: 10px;
- cursor: pointer;
- object-fit: contain;
- }
- .word_box>.word_bbox>.word_content {
- position: relative;
- z-index: 999;
- text-align: center;
- font-size: 36px;
- margin: 15px;
- font-weight: bold;
- color: #000;
- width: calc(100% - 30px);
- word-break: break-word;
- white-space: pre-line;
- }
- .word_box>.word_bbox>.word_content2 {
- position: relative;
- z-index: 999;
- text-align: left;
- font-size: 16px;
- margin: 15px;
- color: #727272;
- width: calc(100% - 30px);
- word-break: break-word;
- white-space: pre-line;
- /* margin-top: 10px; */
- }
- .o_bottom .audio {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .o_bottom .audio>img {
- width: 75px;
- height: 75px;
- cursor: pointer;
- }
- .o_bottom .audio_word {
- display: flex;
- align-items: center;
- justify-content: center;
- color: #00000099;
- font-size: 16px;
- margin: 10px 0 8px;
- }
- .o_bottom .audio_index {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .audio_index_last,
- .audio_index_next {
- height: 40px;
- width: 40px;
- background: #3681fc;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- }
- .audio_index_last>img,
- .audio_index_next>img {
- width: 15px;
- height: auto;
- }
- .audio_index_last.disabled,
- .audio_index_next.disabled {
- opacity: .6;
- }
- .audio_index_last>img {
- transform: rotate(180deg);
- }
- .audio_index_last {
- margin-right: 20px;
- }
- .audio_index_content {
- color: #000;
- font-size: 16px;
- }
- .audio_index_next {
- margin-left: 20px;
- }
- .audio_ing {
- color: #EE3E3E;
- margin-top: 25px;
- font-size: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .audio_b {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 15px;
- }
- .audio_rerecord {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 15px;
- }
- .audio_rerecord>span {
- display: flex;
- border: 1px solid #3981FA;
- align-items: center;
- color: #3981FA;
- padding: 5px 10px;
- border-radius: 5px;
- cursor: pointer;
- }
- .audio_rerecord>span::before {
- content: '';
- width: 15px;
- height: 15px;
- background: url('../../../assets/icon/englishVoice/restart.png');
- display: block;
- background-size: 100% 100%;
- margin-right: 5px;
- }
- .audio_class {
- background: #3680fb !important;
- margin: 0 !important;
- }
- .audio_b>>>.vueAudioBetter span:before {
- color: #fff;
- }
- .audio_class>>>.slider .process {
- background: #000;
- }
- .audio_b>>>.vueAudioBetter .iconfont:active {
- position: unset !important;
- }
- .time_box {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- margin-top: 25px;
- }
- .time_box>span:nth-child(1) {
- color: #727272;
- font-size: 16px;
- }
- .time_box>span:nth-child(2) {
- /* margin-top: 10px; */
- font-size: 32px;
- color: #3581FC;
- }
- .type_box {
- min-width: 500px;
- width: 70%;
- text-align: right;
- color: #a5a5a5;
- margin-bottom: 10px;
- }
- .sentence_div {
- width: 100%;
- overflow: hidden;
- margin-top: 10px;
- display: flex;
- justify-content: flex-end;
- }
- .sentence_div>img {
- width: 60px;
- height: 60px;
- object-fit: cover;
- cursor: pointer;
- border-radius: 4px
- }
- .star_box {
- display: flex;
- align-items: center;
- margin-bottom: 10px
- }
- .star_box>.star {
- width: 25px;
- height: 25px;
- display: block;
- background-image: url('../../../assets/icon/englishVoice/star-no.png');
- background-size: 100% 100%;
- }
- .star_box>.star+.star {
- margin-left: 5px;
- }
- .star_box>.starA {
- background-image: url('../../../assets/icon/englishVoice/star.png');
- }
- </style>
|