前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开发一个 Streamlit 录音组件(二)——支持 iOS 页面

开发一个 Streamlit 录音组件(二)——支持 iOS 页面

原创
作者头像
dandelion1990
修改2024-03-29 22:19:52
4580
修改2024-03-29 22:19:52
举报
文章被收录于专栏:dandelion1990的专栏

上一篇文章用 Streamlit 写了一个录音按钮的组件,实现了按下去时开始录音、放开结束录音的功能。但是只支持桌面端网页用鼠标点击,这次对齐进行扩展,使其能够实现在手机端按下录音的功能。

Touch 事件

在桌面端监听的是鼠标的 mousedown/mouseup 事件,但是在移动端则是手指触屏屏幕的事件 touchstart/touchend,因此需要修改按钮的监听事件。另外之前采用样式中 :hover 来实现按下时按钮颜色的变化,现在使用一个变量来控制

代码语言:vue
复制
<template>
    <div class="button-container">
      <button 
        @touchstart="startRecording"
        @touchcancel="stopRecording"
        @touchend="stopRecording"
        @mousedown="startRecording"
        @mouseup="stopRecording"
        @mouseleave="stopRecording"
        class="red-round-button" :style="{ backgroundColor: buttonColor }" ></button>
    </div>
    <audio ref="audioPlayer" controls class="audio-player"></audio>
</template>


<script setup>
...
const buttonColor = ref('red');
const dynamicStyles = computed(() => {
  return {
    width: props.args.width,
    height: props.args.height,
    backgroundColor: buttonColor
  };
});
...
</script>

另外,移动端长按按钮的话会唤出 Text Selection,需要取消在监听时间时取消掉,详见 Prevent text selection on tap and hold on iOS 13 / Mobile Safari

代码语言:js
复制
function startRecording(event) {
  event.preventDefault();
  ...
}
function stopRecording(event) {
  event.preventDefault();
  ...
}

录音格式兼容

由于 iOS 的浏览器录制的音频格式与桌面端浏览器不一样(参考 MediaRecorder: isTypeSupported() static method),需要在代码中先判断平台,再根据平台决定录音格式,其中桌面 Chrome 格式为 webm/opus,iOS Safari 为 mp4/aac,然后要将对应格式传回组件返回值

代码语言:js
复制
const isIOS = ref(false);

function checkPlatform() {
  if (navigator.userAgentData) {
    console.log(navigator.userAgentData)
    // Use userAgentData for modern browsers
    navigator.userAgentData.getHighEntropyValues(["platform"])
      .then(ua => {
        if (/iPhone|iPad|iPod/.test(ua.platform)) {
          isIOS.value = true;
        }
      });
  } else {
    // Fallback for browsers that do not support userAgentData
    const userAgent = navigator.userAgent;

    console.log(navigator.userAgent)
    if (/iPhone|iPad|iPod/.test(userAgent)) {
      isIOS.value = true;
    }
  }
}

// 在录音时根据平台选择格式
function stopRecording(event) {
  event.preventDefault();
  if (mediaRecorder.value && mediaRecorder.value.state !== 'inactive') {
    mediaRecorder.value.stop();
    mediaRecorder.value.onstop = async function() {
      let format = 'webm';
      if (isIOS.value) {
        format = 'mp4'
      }
      const audioBlob = new Blob(audioChunks.value, { type: 'audio/' + format });
      const reader = new FileReader();
      reader.onload = function(event) {
        if (event.target && event.target.result) {
          const dataUrl = event.target.result;
          const base64 = dataUrl.split(',')[1]; // Extract the base64 part
          Streamlit.setComponentValue({data: base64, format: format}); // 将数据与格式回传
        } else {
          console.log('Failed to read Blob as base64');
        }
      };
      reader.readAsDataURL(audioBlob);
    };
  }
}

onMounted(() => {
  // 先判断平台
  checkPlatform();
});

python 代码也要做对应修改

代码语言:python
代码运行次数:0
复制
def record_button(size, key=None):
    component_value = _component_func(size=size, key=key, default=None)
    if component_value:
        component_value['data'] = base64.b64decode(component_value['data'])
    return component_value

audio = record_button(size='20px')
if audio:
    audio_data, _format = audio['data'], audio['format']
    print(f'len: {len(audio_data)}')
    st.audio(audio_data)
    buffer = io.BytesIO(audio_data)
    try:
        if _format == 'mp4':
            audio = AudioSegment.from_file(buffer, codec="aac")
        else:
            audio = AudioSegment.from_file(buffer, codec="opus")
    
        audio = audio.set_frame_rate(16000).export(format="mp3").read()
    
        query = flash_recognition(audio)
        st.markdown(f'you said: {query}')
        
        reply = completion(query)
        st.markdown(f'reply: {reply}')
    
    except Exception as e:
        st.error(e)

调试

手机的页面没有 F12 开发者工具不方便调试页面,好在 Apple 的 Mac 上的 Safari 可以打开手机 Safari 页面的调试工具

  1. 手机打开设置 -> Safari -> 高级 -> 网页检查器
  2. 打开 Mac Safari -> Settings -> Advanced -> Show features for web developers

具体步骤参考 Develop menu

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Touch 事件
  • 录音格式兼容
  • 调试
相关产品与服务
云开发 CLI 工具
云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档