微信小程序调用讯飞接口实现录音和获取录音音译的文本 前端部分 包含图片、视频的上传功能

时间的3是三秒还没修改格式 问题不大 凑合着看一眼弄了个啥 单纯为了记录 需要的同学得自己找需用用到的地方 我多少写了点注释

wxml部分:

<view class="wrap">
  <el-form :inline="true" :model="form">
    <view class="white-box" wx:for="{{activityMaterials}}" wx:key="index">
      <view class="title-box">
        <view class="yellow-fence"></view>
        <view class="title-txt-part" wx:if="{{!item.isEdit}}">
          <view class="v1">{{item.title}}</view>
          <image src="/image/icon_edit.png" class="icon-edit" data-idx="{{index}}" bindtap="titleHandle" />
        </view>
        <input wx:if="{{item.isEdit}}" type="text" value="" data-idx="{{index}}" class="title-input" placeholder="请输入标题" bindblur="inputBlurHandle" />   
        <image src="/image/icon_close_black.png" data-idx="{{index}}" class="icon-close-black" bindtap="deleteHandle"></image>     
      </view>

      <view class="textarea-box-wrap">

        <view class="voice-box" wx:if="{{item.recordArr.length > 0}}">
          <!--这里是录音的显示区域-->
          <view class="record-item" wx:for="{{item.recordArr}}" wx:key="txt" wx:for-item="oItem" wx:for-index="oIndex">
            <view class="record-list" data-pidx="{{index}}" data-idx="{{oIndex}}" bindtap="playHandle">            
              <image src="{{oItem.played == true ? '/image/icon_pause.png' : '/image/icon_video.png'}}" class="icon-video" />
              <text class="t1">语音</text>
              <text class="t2">00:{{oItem.time}}</text>
            </view>
            <view class="record-txt" wx:if="{{oItem.showTxt}}">{{oItem.txt}}</view>
          </view>

          <!-- <view class="record-item">
            <view class="record-list">            
              <image src="/image/icon_video.png" class="icon-video" />
              <text class="t1">语音</text>
              <text class="t2">00:23</text>
            </view>
            <view class="record-txt">该生聪明伶俐,乐于助人,和同学们相处融洽,尊师重道,就是不学习,感觉没别的啥缺点</view>
          </view> -->

        </view>

        <textarea class="textarea-box" value="{{item.content}}" data-idx="{{index}}" bindblur="textareaBlurHandle" placeholder="请输入内容"></textarea>
        <!--这里是中间那个录音按钮-->
        <button class="record-btn" data-idx="{{index}}" bindtap="recordHandle">
          <image src="/image/icon_record_gray.png" wx:if="{{!item.recordState}}" class="icon-record" />
          <image src="/image/icon_record_red.png" wx:else="{{item.recordState}}" class="icon-record" />
        </button>
      </view>
                  
      <view class="material-box">
        <button class="upload-box" data-idx="{{index}}" bindtap="uploadFile">
          <image src="/image/icon_photo.png" class="icon-photo" />
          上传图片、视频
        </button>
        
        <block wx:for="{{activityMaterials[index].material}}" wx:for-item="mItem" wx:for-index="mIndex" wx:key="url">
          <view class="material-list" wx:if="{{mItem.type == 'img'}}">
            <image src="/image/icon_close.png" class="icon-close" data-pidx="{{index}}" data-idx="{{mIndex}}" bindtap="closeHadle" />
            <image src="{{mItem.url}}" data-src="{{mItem.url}}" data-pidx="{{index}}" data-idx="{{mIndex}}" bindtap="preview" class="material-list-m2" mode="aspectFill"></image>
          </view>
          <view class="material-list" wx:if="{{mItem.type == 'mp4'}}">
            <image src="/image/icon_close.png" class="icon-close" data-pidx="{{index}}" data-idx="{{mIndex}}" bindtap="closeHadle" />
            <video src="{{mItem.url}}" data-src="{{mItem.url}}" class="material-list-m2" mode="aspectFill"></video>
          </view>
        </block>
      </view>

    </view>

    <view class="add-box" bindtap="addListHandle">
      +添加
    </view>

    <view class="save-btn" bindtap="save">提交</view>
  </el-form>
</view>

 js部分
 

const app = getApp()
const util = require('../../utils/util.js');
const api = require('../../config/api.js');
const BASE_URL = app.globalData.BASE_URL
let lock = false

//**************重点 该录音功能亲测如果超过三秒不继续录音会自动结束录音 还得手动关闭录音状态**************
//录音部分-start
const innerAudioContext = wx.createInnerAudioContext({
  useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
})
const recorderManager = wx.getRecorderManager();
var wxst; //语音websocket
var status = 0; // 音频的状态
var iatResult = [] // 识别结果
const searchoptions = {
  duration: 1000 * 60,
  sampleRate: 16000,
  numberOfChannels: 1,
  encodeBitRate: 48000,
  format: 'mp3',
  frameSize: 6
}
//录音部分-end

Page({
  data: {
    coursewareId: '',
    form: {},
    activityMaterials: [],
    isFromReport: false,
    info: {},    
    //recordArr: [], recordArr率属于activityMaterials的子集 //音频数组 包含三个字段 url->mp3格式文件 txt:MP3的文字版的文本 time: 录音的时间 played:是否正在播放
    parentIndex: null,

    //录音部分-start
    srcMic: '',
    edit_text_max: 200,
    remain_length: 200,
    edit_text: "",
    is_focus: false,
    tips: "",
    index: -1,
    voicePath: "",
    //语音
    //recordState: false, //录音状态 该字段纳入作为activityMaterials的子级 由activityMaterials统一调配
    contentTxt: '', //内容
    firstSend: true,
    //录音部分-end
  },

  onLoad(options) {
    //console.log(options)
    if (options.title) { //自定义顶部导航title
      wx.setNavigationBarTitle({
        title: options.title
      })
    }
    const userInfo = wx.getStorageSync('userInfo');
    this.setData({
      userInfo,
      coursewareId: options.coursewareId,
      isFromReport: options.isFromReport ? true : false,
      title: options.title,
      info: {
        thumb: options.thumb,
        title: options.title,
        updateTime: options.updateTime
      },
      activityMaterials: []
    })
    lock = false
    //先调用接口 如果length为零 那么新增一个对象    
    this.loadData()
    this.initRecord()//这个是录音的内容要调用    
  },

  onShow: function () { //这是录音的马蜂窝
    var that = this;
    recorderManager.onStart(() => {//开始录音时触发
      status = 0;
      iatResult = []
      //console.log('recorder start');
      that.data.firstSend = false;
    });
    recorderManager.onError((res) => {//错误回调
      //console.log(res);
    });
    recorderManager.onStop((res) => {//结束录音时触发
      //console.log('recorder stop')
      //console.log(res)
      let otime = (res.duration/1000).toFixed(0)
      status = 2;
      var sendsty = '{"data":{"status":2,"audio":"","format":"audio/L16;rate=8000","encoding":"raw"}}'
      wxst.send({
        data: sendsty
      })
      wx.uploadFile({
        // 模拟https
        url: BASE_URL + 'common/uploadMediaToTencent', //需要用HTTPS,同时在微信公众平台后台添加服务器地址
        filePath: res.tempFilePath, //上传的文件本地地址
        name: 'file',
        //附近数据,这里为路径
        success: function(result) {          
          // console.log("--结束录音--")
          // console.log(that.data.contentTxt)
          // console.log(JSON.parse(result.data).url)
          // console.log(otime)
          if(that.data.contentTxt){            
            //recordArr: []//音频数组 包含三个字段 url->mp3格式文件 txt:MP3的文字版的文本 time: 录音的时间 played:是否正在播放
            let ourl = JSON.parse(result.data).url
            let pidx = that.data.parentIndex
            let params = {
              url: ourl,
              txt: that.data.contentTxt,
              time: that.timeHandle(otime),//这个时间是用来显示的
              played: false,
              showTxt: false,
            }
            let oarr = that.data.activityMaterials 
            
            oarr.forEach((item) => {
              item.recordArr = item.recordArr && item.recordArr.length > 0 ? item.recordArr : []
            })
              
            oarr[pidx].recordArr.push(params)
            that.setData({
              activityMaterials: oarr
            })         
            //console.log(that.data.activityMaterials)
          }else{
            //console.log("木有内容啊")
          }
        },
        fail: function(err) {
          //console.log(err)
        }
      })
    });
    recorderManager.onFrameRecorded((res) => {//每帧触发
      const that = this
      const { frameBuffer, isLastFrame } = res
      let params = {
        'common': {
          'app_id': '57198f05'
        },
        'business': {
          'language': 'zh_cn', //⼩语种可在控制台--语⾳听写(流式)--⽅⾔/语种处添加试⽤
          'domain': 'iat',
          'accent': 'mandarin', //中⽂⽅⾔可在控制台--语⾳听写(流式)--⽅⾔/语种处添加试⽤
          'vad_eos': 1000,
          'dwa': 'wpgs' //为使该功能⽣效,需到控制台开通动态修正功能(该功能免费)
        },
        'data': {
          'status': 0,
          'format': 'audio/L16;rate=16000',
          'encoding': 'lame',
          'audio': wx.arrayBufferToBase64(frameBuffer)
        }
      }
      // 拼接数据
      let status = 0
      if (this.data.firstSend) {
        this.data.firstSend = false
      } else {
        if (isLastFrame) {
          status = 2
        } else {
          status = 1
        }
      }
      params.data.status = status
      wx.sendSocketMessage({
        data: JSON.stringify(params),
        success: (data) => {
          console.log('send success:' + JSON.stringify(data))
          //that.resetRecordState()
        },
        fail: (err) => {
          console.log('send error:' + JSON.stringify(err))
          //中断录音的时候
          //that.resetRecordState()
        },
        completed: () => {
          if (isLastFrame) {
            // wx closeSocket
          }
        }
      })
    })
  },

  timeHandle(time){
    if(time < 9){
      return '0' + time
    }else{
      return time
    }
  },

  //重置录音按钮状态
  resetRecordState(){
    let activityMaterials = this.data.activityMaterials
    activityMaterials[this.data.parentIndex].recordState = false
    this.setData({
      activityMaterials: activityMaterials
    })
  },

  save() {//这里还没改 不重要的文件
    if (lock) return
    lock = true
    //处理过滤activityMaterials数据
    let actArr = this.data.activityMaterials.map(function (item) {
      let oarr = []
      //转换数据格式
      oarr[0] = {
        content: item.content
      }
      for (let i in item.material) {
        oarr.push({
          content: item.material[i].url
        })
      }
      return {
        title: item.title,
        paragraphs: oarr
      }
    })
    for (let i in actArr) {
      //title等于编辑标题就代表没编辑过 paragraphs[0].content的值为空就代表textare没编辑过 paragraphs[1]不存在或者content为空就代表没编辑过
      if (actArr[i].title == '编辑标题' && !actArr[i].paragraphs[0].content && (!actArr[i].paragraphs[1] || !actArr[i].paragraphs[1].content)) {
        actArr.splice(i, 1)
      }
    }
    if (actArr.length == 0) {
      wx.showToast({
        title: '请先编辑材料!',
        icon: 'none',
        duration: 2000
      })
      lock = false
      return
    }
    util.request(api.activityPreparationSave, {
      teacherId: this.data.userInfo.userId,
      classId: this.data.userInfo.deptId,
      coursewareId: this.data.coursewareId,
      activityMaterials: actArr
    }, 'POST', 'application/json').then(res => {
      if (res.code = 200) {
        wx.showToast({
          title: '提交成功!',
          icon: 'error',
          duration: 2000
        })
        //判断是不是报告那边跳转过来的
        if (this.data.isFromReport) {
          let oinfo = this.data.info
          wx.redirectTo({
            url: '../reportdetail/reportdetail?coursewareId=' + this.data.coursewareId + '&title=' + oinfo.title + '&thumb=' + oinfo.thumb + '&updateTime=' + oinfo.updateTime
          })
        } else {
          wx.navigateBack({
            delta: 1
          });
        }
        lock = false
      } else {
        wx.showToast({
          title: res.msg,
          icon: 'error',
          duration: 2000
        })
        lock = false
      }
    });
  },

  loadData() {
    util.request(api.activityPreparationList + this.data.userInfo.userId + '&coursewareId=' + this.data.coursewareId + '&classId=' + this.data.userInfo.deptId, '', 'get').then(res => {
      if (res.code = 200) {
        let odata = res.data
        if (odata && odata.length == 0) {
          let obj = this.data.activityMaterials
          obj.push({
            title: '编辑标题',
            isEdit: false,
            content: '',
            material: []
          })
          this.setData({
            activityMaterials: obj
          })
        } else {
          //重组数据
          //type 1图片 3视频 
          let oarr = odata.map(function (item) {
            let paragraphs = []
            for (let i in item.paragraphs) {
              paragraphs.push({
                url: item.paragraphs[i].content,
                type: item.paragraphs[i].type == '3' ? 'mp4' : item.paragraphs[i].type == '1' ? 'img' : ''
              })
            }
            return {
              title: item.title ? item.title : '编辑标题',
              isEdit: false,
              content: item.content,
              material: paragraphs
            }
          })
          //console.log(oarr)
          this.setData({
            activityMaterials: oarr
          })
        }
      } else {
        wx.showToast({
          title: res.msg,
          icon: 'error',
          duration: 2000
        })
      }
    });
  },

  addListHandle() {
    let obj = this.data.activityMaterials
    obj.push({
      title: '编辑标题',
      isEdit: false,
      content: '',
      material: []
    })
    this.setData({
      activityMaterials: obj
    })
  },

  titleHandle(e) {
    let obj = this.data.activityMaterials
    let idx = e.currentTarget.dataset.idx
    obj[idx].isEdit = true
    this.setData({
      activityMaterials: obj
    })
  },
  inputBlurHandle(e) {
    let oval = e.detail.value
    let obj = this.data.activityMaterials
    let idx = e.currentTarget.dataset.idx
    if (oval) {
      obj[idx].title = oval
    }
    obj[idx].isEdit = false
    this.setData({
      activityMaterials: obj
    })
  },
  textareaBlurHandle(e) {
    let oval = e.detail.value
    let obj = this.data.activityMaterials
    let idx = e.currentTarget.dataset.idx
    if (oval) {
      obj[idx].content = oval
    }
    this.setData({
      activityMaterials: obj
    })
  },

  preview(e) {
    let currentUrl = e.currentTarget.dataset.src
    let pidx = e.currentTarget.dataset.pidx //父级循环的index
    const oarr = []
    for (let i in this.data.activityMaterials[pidx].material) {
      oarr.push(this.data.activityMaterials[pidx].material[i].url)
    }
    wx.previewImage({
      current: currentUrl, // 当前显示图片的http链接
      urls: oarr // 需要预览的图片http链接列表
    })
  },

  closeHadle(e) {
    //console.log(e)
    const that = this
    wx.showModal({
      title: '',
      content: '是否删除素材',
      success(res) {
        if (res.confirm) {
          let obj = that.data.activityMaterials
          let pidx = e.currentTarget.dataset.pidx //父级循环的index
          let idx = e.currentTarget.dataset.idx //子级循环的index
          obj[pidx].material.splice(idx, 1)
          that.setData({
            activityMaterials: obj
          })
        } else if (res.cancel) {
          //console.log('用户点击取消')
        }
      }
    })
  },

  //上传图片、视频
  uploadFile: function (e) {
    const that = this
    let obj = this.data.activityMaterials
    let pidx = e.currentTarget.dataset.idx
    wx.chooseMedia({
      count: 9, // 设置为需要上传的文件数量
      mediaType: ['image', 'video'],
      success: function (res) {
        const files = res.tempFiles;
        // 遍历选择的文件数组,依次上传每个文件
        files.forEach(function (file) {
          const tempFilePath = file.tempFilePath;
          wx.uploadFile({
            url: BASE_URL + 'common/uploadMediaToTencent',
            filePath: tempFilePath,
            name: 'file',
            success: function (res) {
              //console.log(res)
              let ores = JSON.parse(res.data)
              //每个数组里添加一个type值是mp4或者img,在for循环里通过type赋值到mp4或者img里面
              let otype = that.getFileExtension(ores.url)
              if (otype) {
                let params = {
                  url: ores.url,
                  type: otype
                }
                obj[pidx].material.push(params)
              }
              that.setData({
                activityMaterials: obj
              })
            },
            fail: function (res) {
              //console.log(res.errMsg);
              // 处理上传失败后的逻辑
            }
          })
        });
      }
    })
  },
  //用一个方法来判断 返回的文件是mp4 还是图片
  getFileExtension(url) {
    const dotIndex = url.lastIndexOf('.');
    const extension = url.substring(dotIndex + 1);
    if (/(jpg|jpeg|png)$/.test(extension.toLowerCase())) {
      return 'img'
    } else if (/(mp4|avi|mov)$/.test(extension.toLowerCase())) {
      return 'mp4'
    }
    return false
  },

  deleteHandle(e) {
    const that = this
    wx.showModal({
      title: '',
      content: '是否删除',
      success(res) {
        if (res.confirm) {
          let obj = that.data.activityMaterials
          let idx = e.currentTarget.dataset.idx //子级循环的index
          obj.splice(idx, 1)
          that.setData({
            activityMaterials: obj
          })
        } else if (res.cancel) {
          //console.log('用户点击取消')
        }
      }
    })
  },

  //识别语音 -- 初始化 从这里开始是录音的内容 一直到结束
  initRecord: function () {
    var that = this;
    wx.onSocketOpen((res) => {// websocket打开
      //console.log('监听到 WebSocket 连接已打开' + res);
    })
    wx.onSocketError((err) => {//连接失败
      //console.log('websocket连接失败', err);
      wx.showToast({
        title: 'websocket连接失败',
        icon: 'none',
        duration: 2000,
        mask: false
      })
    })
    wx.onSocketMessage((res) => {//接收返回值
      var data = JSON.parse(res.data)
      //console.log('----------------')
      //console.log(data)
      if (data.code != 0) {
        //console.log("error code " + data.code + ", reason " + data.message)
        return
      }
      let str = ""
      if (data.data.status == 2) {//最终识别结果
        // data.data.status ==2 说明数据全部返回完毕,可以关闭连接,释放资源
        wxst.close();
      } else {//中间识别结果
      }
      iatResult[data.data.result.sn] = data.data.result
      if (data.data.result.pgs == 'rpl') {
        data.data.result.rg.forEach(i => {
          iatResult[i] = null
        })
      }
      iatResult.forEach(i => {
        if (i != null) {
          i.ws.forEach(j => {
            j.cw.forEach(k => {
              str += k.w
            })
          })
        }
      });
      // console.log('这个是中间的语音识别结果')
      // console.log(str)
      that.setData({
        contentTxt: str //这个是中间的语音识别结果
      })
      if(!this.data.contentTxt){
        wx.showToast({
          title: '识别失败,请重新录入',
          icon: 'none',
          duration: 2000,
          mask: false
        })        
        return
      }
    })
    wx.onSocketClose((res) => {//WebSocket连接已关闭!
      //var that = this;
      recorderManager.stop();
      // var str = that.data.contentTxt;
      // console.log(str);
      // str = str.replace(/\s*/g, "");//去除空格
      // if (str.substr(str.length - 1, 1) == "。") {//去除句号
      //   str = str.substr(0, str.length - 1);
      // }
      // console.log('这个是最后确定的语音识别结果', str)
      // that.setData({
      //   contentTxt: str//这个是最后确定的语音识别结果
      // })
      //console.log('WebSocket连接已关闭!')
    })
  },

  //录音和停止录音操作
  recordHandle(e){
    let oactivityMaterials = this.data.activityMaterials
    let parentIndex = e.currentTarget.dataset.idx
    
    this.setData({//获取父级的下标 后面录音结束后给对应的模块赋值
      parentIndex: parentIndex
    })    
    //改成点击事件
    if(!oactivityMaterials[parentIndex].recordState){
      wx.showToast({
        title: '开始录音',
        icon: 'none',
        duration: 1000
      })
      //兄弟节点的录音按钮改成灰色
      if(oactivityMaterials.length > 1){
        for(let i in oactivityMaterials){
          oactivityMaterials[i].recordState = false
        }
        this.setData({
          activityMaterials: oactivityMaterials
        })
      }
      oactivityMaterials[parentIndex].recordState = true
      this.setData({
        activityMaterials: oactivityMaterials  //录音状态
      })
      wx.getSetting({//查看用户有没有开启语音权限
        success(res) {
          if (res.authSetting['scope.record']) {
            wx.authorize({
              scope: 'scope.record',
              success() {
                var xfurl = "";
                wx.request({//请求接口 获取讯飞语音鉴权
                  url: BASE_URL + 'assistant/url',
                  method: "get",
                  header: {
                    'content-type': 'application/json' // 默认值
                  },
                  success: function (res) {
                    //console.log('鉴权结果start:');
                    //console.log(res);
                    if (res.statusCode == "200" && res.data) {
                      xfurl = res.data;
                      wxst = wx.connectSocket({ // 开启websocket连接
                        url: xfurl,
                        method: 'GET',
                        success: function (res) {
                          recorderManager.start(searchoptions);//开始录音
                        }
                      });
                    } else {
                      wx.showToast({
                        title: '获取语音鉴权失败',
                        icon: 'none',
                        mask: true,
                        duration: 3000
                      })
                    }
                  },
                  fail: function () {
                    wx.showToast({
                      title: '获取语音鉴权失败',
                      icon: 'none',
                      mask: true,
                      duration: 3000
                    })
                  }
                })
              },
              fail() {
                wx.showModal({
                  title: '微信授权',
                  content: '您当前未开启语音权限,请在右上角设置(···)中开启“录音功能”',
                  showCancel: false,
                  success(res) {
                    if (res.confirm) {
                      //console.log('用户点击确定')
                    }
                  }
                })
              }
            })
          } else {
            wx.showModal({
              title: '微信授权',
              content: '您当前未开启语音权限,请在右上角设置(···)中开启“录音功能”',
              showCancel: false,
              success(res) {
                if (res.confirm) {
                  //console.log('用户点击确定')
                }
              }
            })
          }
        }
      })
    }else{
      oactivityMaterials[parentIndex].recordState = false
      this.setData({
        activityMaterials: oactivityMaterials
      })
      recorderManager.stop();
    }    
  },

  //播放操作
  playHandle(e){
    const that = this
    let idx = e.currentTarget.dataset.idx
    let pidx = e.currentTarget.dataset.pidx
    //recordArr的字段有url/txt/time/played/showTxt    
    let activityMaterials = this.data.activityMaterials
    let orecordArr = activityMaterials[pidx].recordArr[idx]
    
    innerAudioContext.src = orecordArr.url    
    if(!orecordArr.played){
      //查找兄弟节点 把所有的played状态改成false
      for(let i in activityMaterials){
        for(let j in activityMaterials[i].recordArr){
          activityMaterials[i].recordArr[j].played = false
        }
      }
      // if(activityMaterials && activityMaterials.length > 1){
      //   that.setData({
      //     activityMaterials: activityMaterials
      //   })
      // }
      //播放
      orecordArr.played = true
      innerAudioContext.play() // 播放      
      innerAudioContext.onEnded(() => {
        //console.log('语音播放结束');     
        orecordArr.played = false
        that.setData({
          activityMaterials: activityMaterials
        })
      });
    }else{
      //关闭
      orecordArr.played = false
      innerAudioContext.stop() // 停止
    }       
    this.setData({
      activityMaterials: activityMaterials
    })    
      
  }

})

wxss部分

.wrap{ padding: 22rpx 10rpx 100rpx 10rpx;}
.white-box{ margin-bottom: 22rpx; padding: 22rpx; width: 730rpx; box-sizing: border-box; background: #fff; border-radius: 25rpx;}
.title-box,.title-txt-part{ display: flex; align-items: center;}
.title-box{ position: relative;}
.icon-close-black{ position: absolute; right: 0; display: block; width: 20rpx; height: 21rpx;}
.icon-edit{ margin-left: 10rpx; width: 31rpx; height: 30rpx;}
.yellow-fence{ margin-right: 10rpx; width: 6rpx; height: 30rpx; background: #ffb81c; border-radius: 3rpx;}
.title-txt-part{ font-size: 28rpx; font-weight: bold;}
.title-input{ padding-left: 16rpx; width: 360rpx; height: 60rpx; border:1rpx solid #ddd; border-radius: 10rpx; font-size: 26rpx;}

.material-box{ margin-top: 22rpx; display: flex; justify-content: flex-start; flex-wrap: wrap;}
.upload-box{ margin: 0 25rpx 25rpx 0; padding: 0; display: flex; justify-content: center; align-items: center; width: 310rpx; height: 186rpx; background: #f0f0f0; font-size: 25rpx; color: #111; border: 0; border-radius: 22rpx;}
button::after {border: none;}
.icon-photo{ margin-right: 10rpx; display: block; width: 93rpx; height: 85rpx;}
.material-list{ position: relative; margin: 0 25rpx 25rpx 0; width: 310rpx; height: 186rpx;}
.material-list-m2{ width: 100%; height: 100%; border-radius: 22rpx;}
.icon-close{ position: absolute; top: 10rpx; right: 10rpx; z-index: 999; display: block; width: 50rpx; height: 50rpx;}
.add-box{ margin: 22rpx auto 0 auto; width: 270rpx; text-align: center; line-height: 60rpx; font-size: 35rpx; color: #ffb81c; font-weight: bold; border-bottom: 3rpx solid #ffb81c;}
.save-btn{ margin: 100rpx auto 0 auto; width: 330rpx; height: 84rpx; text-align: center; line-height: 84rpx; background: #ffb81c; font-size: 30rpx; color: #111; font-weight: bold; border-radius: 42rpx;}


.textarea-box-wrap{ margin-top: 22rpx; padding: 22rpx; display: flex; flex-direction: column; justify-content: center; height: 580rpx; background: #f0f0f0; border-radius: 25rpx;}
.textarea-box{ flex:1; height: 100%; box-sizing: border-box; font-size: 25rpx; color: #111;}
.voice-box{ margin-bottom: 20rpx; max-height: 200rpx; overflow-y: scroll; box-sizing: border-box; font-size: 25rpx; color: #111;}
.videoBtn {width: 50%;}
.videoBtn text{color:#fff;}
.videoBtnBg {background: #bdb4b4;}
.startYuyinImage {  
  position: fixed;
  top: 200rpx;
  left: 50%;
  z-index: 99;
  transform: translateX(-50%);
  display:flex;justify-content:center;flex-flow: column;
  width: 220rpx;
  height: 220rpx;
  text-align: center;
  background: rgba(0, 0, 0, 0.1);  
  color: #fff;
  font-size: 24rpx;
  border-radius: 50%;  
}
.startYuyinImage cover-image { margin:0 auto; width:80rpx;height: 80rpx;}
.startYuyinImage cover-view { margin-top: 22rpx;}
.musicd {
  position: fixed;
  z-index: 9999;
  top: 10%;
  left: 4%;
}
.musicd image {
  width: 100rpx;
  height: 100rpx;
  z-index: 999;
}

.icon-record{ display: block; width: 70rpx; height: 70rpx;}
.record-btn{ margin: 0 auto; padding: 0; width: 70rpx; height: 70rpx; background: transparent; border-radius: 50%;}
button::after{border: none;}
.record-list{ padding-left: 18rpx; display: flex; align-items: center; box-sizing: border-box; width: 640rpx; height: 74rpx; background: #fff; color: #19b2ff; border-radius: 18rpx;}
.icon-video{ display: block; width: 56rpx; height: 55rpx;}
.record-list .t1{ margin: 0 22rpx;}
.record-txt{ padding:10rpx 10rpx 0 10rpx; font-size: 24rpx; color: #19b2ff;}
.record-item{ margin-bottom: 22rpx;}
.record-item:last-child{ margin-bottom: 0;}

json不用调用什么

页面我也还没写完 单纯的记录一下这个功能

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值