JayJiaJun
JayJiaJun
  • 发布:2025-10-17 14:07
  • 更新:2025-10-17 14:11
  • 阅读:26

【报Bug】uniapp在小程序端,安卓设备音频播放正常,ios无法播放也无报错

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: win11 22631

HBuilderX类型: 正式

HBuilderX版本号: 4.76

第三方开发者工具版本号: 1.06.2504010

基础库版本号: 1.0.0

项目创建方式: HBuilderX

示例代码:

/**  
 * 获取百度 Access Token(跨平台)  
 */  
async getAccessToken() {  
  const AK = "YOUR_BAIDU_API_KEY";         
  const SK = "YOUR_BAIDU_SECRET_KEY";      
  const BASE_API = 'https://your-domain.com/api';  

  const cached = uni.getStorageSync('baidu_access_token');  
  if (cached) {  
    const { token, expires_at } = JSON.parse(cached);  
    if (Date.now() < expires_at) {  
      return token;  
    }  
  }  

  const url = `${BASE_API}/baidu/token?grant_type=client_credentials&client_id=${AK}&client_secret=${SK}`;  

  try {  
    const [error, res] = await uni.request({  
      url,  
      method: 'POST',  
      header: { 'Content-Type': 'application/x-www-form-urlencoded' }  
    });  

    if (error) throw error;  
    if (res.statusCode !== 200) throw new Error(`HTTP ${res.statusCode}`);  

    const data = res.data;  
    if (data.access_token) {  
      uni.setStorageSync('baidu_access_token', JSON.stringify({  
        token: data.access_token,  
        expires_at: Date.now() + (data.expires_in - 600) * 1000  
      }));  
      return data.access_token;  
    } else {  
      throw new Error(data.error_description || '获取token失败');  
    }  
  } catch (error) {  
    console.error('获取 Access Token 失败:', error);  
    throw new Error(`获取百度语音 token 失败:${error.message}`);  
  }  
},  

/**  
 * 预览音频(跨平台兼容,使用 MP3)  
 */  
async previewAudio() {  
  if (!this.newAudio.text?.trim()) {  
    uni.showToast({ title: '请输入需要合成的文本', icon: 'none' });  
    return;  
  }  
  if (this.newAudio.text.length > 30) {  
    uni.showToast({ title: '文本不能超过30个字', icon: 'none' });  
    return;  
  }  

  this.previewLoading = true;  
  try {  
    const BASE_API = 'https://your-domain.com/api'; // ← 已脱敏  
    const deviceInfo = uni.getSystemInfoSync();  
    const cuid = `uniapp_${(deviceInfo.deviceId || deviceInfo.model || 'unknown').replace(/\s+/g, '_')}_${Date.now()}`;  
    const encodedText = encodeURIComponent(this.newAudio.text);  

    const params = {  
      tex: encodedText,  
      cuid,  
      ctp: '1',  
      lan: 'zh',  
      spd: this.newAudio.spd.toString(),  
      pit: this.newAudio.pit.toString(),  
      vol: this.newAudio.vol.toString(),  
      per: this.newAudio.per.toString(),  
      aue: '3' // MP3 格式  
    };  

    const accessToken = await this.getAccessToken();  
    params.tok = accessToken;  

    const queryString = Object.keys(params)  
      .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)  
      .join('&');  

    console.log('【调试】请求参数:', queryString);  

    const [error, res] = await uni.request({  
      url: `${BASE_API}/baidu/tts`,  
      method: 'POST',  
      header: { 'Content-Type': 'application/x-www-form-urlencoded' },  
      data: queryString,  
      responseType: 'arraybuffer'  
    });  

    console.log('【调试】响应状态:', res?.statusCode);  
    console.log('【调试】响应头:', res?.header);  

    if (error) throw error;  
    if (res.statusCode !== 200) {  
      const text = String.fromCharCode.apply(null, new Uint8Array(res.data));  
      throw new Error(`HTTP ${res.statusCode}: ${text.substring(0, 100)}`);  
    }  

    const contentType = (res.header['Content-Type'] || res.header['content-type'] || '').toLowerCase();  
    console.log('【调试】Content-Type:', contentType);  

    if (contentType.includes('application/json')) {  
      const errData = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;  
      throw new Error(`合成失败: ${errData.err_msg || errData.error}`);  
    }  
    if (!contentType.includes('audio')) {  
      console.warn('【警告】非音频响应,尝试转文本预览:');  
      try {  
        const text = String.fromCharCode.apply(null, new Uint8Array(res.data));  
        console.log('【调试】响应文本预览:', text.substring(0, 200));  
      } catch (e) {  
        console.log('【调试】转文本失败:', e);  
      }  
      throw new Error('服务器未返回音频数据');  
    }  

    // 保存为临时 MP3 文件  
    const filePath = `${uni.env.USER_DATA_PATH}/preview_${Date.now()}.mp3`;  
    await new Promise((resolve, reject) => {  
      uni.getFileSystemManager().writeFile({  
        filePath,  
        data: res.data,  
        encoding: '',  
        success: resolve,  
        fail: reject  
      });  
    });  

    // 播放音频  
    if (this.previewAudioElement) {  
      this.previewAudioElement.destroy();  
    }  
    this.previewAudioElement = uni.createInnerAudioContext();  
    this.previewAudioElement.src = filePath;  
    this.previewAudioElement.onError((e) => {  
      console.error('【播放错误】', e);  
      uni.showToast({ title: '播放失败: ' + (e.errMsg || e.errCode), icon: 'none' });  
    });  
    this.previewAudioElement.onEnded(() => {  
      uni.getFileSystemManager().unlink({ filePath, fail: () => {} });  
    });  
    this.previewAudioElement.play();  
    uni.showToast({ title: '音频预览播放中', icon: 'success' });  

  } catch (error) {  
    console.error('【最终错误】语音合成失败:', error);  
    uni.showToast({ title: `语音合成失败: ${error.message}`, icon: 'none' });  
  } finally {  
    this.previewLoading = false;  
  }  
}

操作步骤:

hbuilder运行在微信开发者工具点击按钮,正常播放。同时也发布到微信小程序端,ios无任何报错没有音频播放,安卓可以。

预期结果:

ios端也可以播放

实际结果:

ios端无法播放,安卓端正常播放

bug描述:


? 问题描述

在微信开发者工具中,调用语音合成接口预览音频功能完全正常;在真机调试时,安卓端可以正确使用,但是ios端没有声音播放。

2025-10-17 14:07 负责人:无 分享
已邀请:
DCloud_UNI_JBB

DCloud_UNI_JBB

同样的代码,试试原生微信小程序是否也有这个问题

要回复问题请先登录注册