uniapp上传音频文件到服务器

news2024/9/28 17:31:06

视频教程地址:

【uniapp录音上传组件,将录音上传到django服务器】 https://www.bilibili.com/video/BV1wi4y1p7FL/?share_source=copy_web&vd_source=e66c0e33402a09ca7ae1f0ed3d5ecf7c

  • uniapp 录制音频文件上传到django服务器保存到服务器 ,要求uniapp显示录制进度波形图 请提供完整代码
  • 以下是一个示例代码,演示了如何在uniapp中录制音频文件并将其上传到Django服务器,并在uniapp中显示录制进度波形图。

    在uniapp的页面中,你可以使用uni-voice组件来录制音频,并使用uni-upload组件来上传文件。在Django服务器端,你可以使用Django的文件上传功能来保存音频文件。

    uniapp页面代码(index.vue):

     
<template>
  <view class="container">
    <view class="waveform" :style="{ width: waveformWidth + 'px' }"></view>
    <view class="controls">
      <button @tap="startRecording" :disabled="isRecording">开始录制</button>
      <button @tap="stopRecording" :disabled="!isRecording">停止录制</button>
      <button @tap="uploadFile" :disabled="!recordedFile">上传文件</button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isRecording: false,
      recordedFile: null,
      waveformWidth: 0,
      audioContext: null,
      audioRecorder: null,
      audioChunks: [],
    };
  },
  mounted() {
    this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
  },
  methods: {
    startRecording() {
      this.isRecording = true;
      this.audioChunks = [];
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then((stream) => {
          this.audioRecorder = new MediaRecorder(stream);
          this.audioRecorder.addEventListener('dataavailable', (event) => {
            this.audioChunks.push(event.data);
            this.drawWaveform();
          });
          this.audioRecorder.start();
        })
        .catch((error) => {
          console.error('Error accessing microphone:', error);
        });
    },
    stopRecording() {
      this.isRecording = false;
      this.audioRecorder.stop();
      this.audioRecorder.stream.getTracks().forEach((track) => track.stop());
      this.audioRecorder = null;
      this.recordedFile = new File(this.audioChunks, 'recorded_audio.wav', { type: 'audio/wav' });
    },
    drawWaveform() {
      const waveformElement = this.$refs.waveform;
      const canvas = waveformElement.getContext('2d');
      const width = waveformElement.width;
      const height = waveformElement.height;
      const data = new Uint8Array(this.audioChunks.reduce((acc, chunk) => acc + chunk.byteLength, 0));
      let offset = 0;
      this.audioChunks.forEach((chunk) => {
        const reader = new FileReader();
        reader.onload = () => {
          const array = new Uint8Array(reader.result);
          data.set(array, offset);
          offset += array.length;
          canvas.clearRect(0, 0, width, height);
          canvas.fillStyle = '#000000';
          for (let i = 0; i < width; i++) {
            const value = data[Math.floor(i * (data.length / width))];
            const barHeight = (value / 255) * height;
            canvas.fillRect(i, height - barHeight, 1, barHeight);
          }
        };
        reader.readAsArrayBuffer(chunk);
      });
    },
    uploadFile() {
      const formData = new FormData();
      formData.append('audio', this.recordedFile);
      uni.uploadFile({
        url: 'http://your-django-server/upload/',
        filePath: this.recordedFile.path,
        name: 'audio',
        formData: formData,
        success: (res) => {
          console.log('File uploaded:', res);
        },
        fail: (error) => {
          console.error('Error uploading file:', error);
        },
      });
    },
  },
};
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.waveform {
  width: 300px;
  height: 100px;
  background-color: #f0f0f0;
}

.controls {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

button {
  margin: 0 10px;
}
</style>

在Django服务器端,你需要设置一个视图函数来处理文件上传请求,并将音频文件保存到服务器上的某个目录中。以下是一个简单的示例代码:

 
  • from django.http import JsonResponse
    
    def upload_file(request):
        if request.method == 'POST' and request.FILES.get('audio'):
            audio_file = request.FILES['audio']
            with open('path/to/save/audio.wav', 'wb') as f:
                for chunk in audio_file.chunks():
                    f.write(chunk)
            return JsonResponse({'success': True})
        return JsonResponse({'success': False, 'message': 'Invalid request'})
    

    请将上述代码保存为一个Django视图函数,并将其添加到你的Django项目的URL配置中。

    注意:上述代码仅为示例,你可能需要根据你的具体需求进行适当的修改和调整。

  • 要保存文mp3文件
  • 如果你想保存音频文件为MP3格式,你可以使用lamejs库来将录制的音频文件转换为MP3格式。以下是修改后的示例代码:

    uniapp页面代码(index.vue):

     
<template>
  <view class="container">
    <view class="waveform" :style="{ width: waveformWidth + 'px' }"></view>
    <view class="controls">
      <button @tap="startRecording" :disabled="isRecording">开始录制</button>
      <button @tap="stopRecording" :disabled="!isRecording">停止录制</button>
      <button @tap="convertToMp3" :disabled="!recordedFile">转换为MP3</button>
      <button @tap="uploadFile" :disabled="!mp3File">上传文件</button>
    </view>
  </view>
</template>

<script>
import lamejs from 'lamejs';

export default {
  data() {
    return {
      isRecording: false,
      recordedFile: null,
      mp3File: null,
      waveformWidth: 0,
      audioContext: null,
      audioRecorder: null,
      audioChunks: [],
    };
  },
  mounted() {
    this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
  },
  methods: {
    startRecording() {
      this.isRecording = true;
      this.audioChunks = [];
      navigator.mediaDevices.getUserMedia({ audio: true })
        .then((stream) => {
          this.audioRecorder = new MediaRecorder(stream);
          this.audioRecorder.addEventListener('dataavailable', (event) => {
            this.audioChunks.push(event.data);
            this.drawWaveform();
          });
          this.audioRecorder.start();
        })
        .catch((error) => {
          console.error('Error accessing microphone:', error);
        });
    },
    stopRecording() {
      this.isRecording = false;
      this.audioRecorder.stop();
      this.audioRecorder.stream.getTracks().forEach((track) => track.stop());
      this.audioRecorder = null;
      this.recordedFile = new File(this.audioChunks, 'recorded_audio.wav', { type: 'audio/wav' });
    },
    drawWaveform() {
      const waveformElement = this.$refs.waveform;
      const canvas = waveformElement.getContext('2d');
      const width = waveformElement.width;
      const height = waveformElement.height;
      const data = new Uint8Array(this.audioChunks.reduce((acc, chunk) => acc + chunk.byteLength, 0));
      let offset = 0;
      this.audioChunks.forEach((chunk) => {
        const reader = new FileReader();
        reader.onload = () => {
          const array = new Uint8Array(reader.result);
          data.set(array, offset);
          offset += array.length;
          canvas.clearRect(0, 0, width, height);
          canvas.fillStyle = '#000000';
          for (let i = 0; i < width; i++) {
            const value = data[Math.floor(i * (data.length / width))];
            const barHeight = (value / 255) * height;
            canvas.fillRect(i, height - barHeight, 1, barHeight);
          }
        };
        reader.readAsArrayBuffer(chunk);
      });
    },
    convertToMp3() {
      const wavData = new Uint8Array(this.audioChunks.reduce((acc, chunk) => acc + chunk.byteLength, 0));
      let offset = 0;
      this.audioChunks.forEach((chunk) => {
        const array = new Uint8Array(chunk);
        wavData.set(array, offset);
        offset += array.length;
      });
      const wavFile = new Blob([wavData], { type: 'audio/wav' });
      const mp3Encoder = new lamejs.Mp3Encoder(1, this.audioContext.sampleRate, 128);
      const samples = new Int16Array(wavData.buffer);
      const mp3Data = [];
      let remaining = samples.length;
      let index = 0;
      while (remaining >= 0) {
        const bufferSize = Math.min(remaining, 1152);
        const buffer = samples.subarray(index, index + bufferSize);
        const mp3Buffer = mp3Encoder.encodeBuffer(buffer);
        mp3Data.push(mp3Buffer);
        remaining -= bufferSize;
        index += bufferSize;
      }
      const mp3Buffer = mp3Encoder.flush();
      mp3Data.push(mp3Buffer);
      const mp3DataBlob = new Blob(mp3Data, { type: 'audio/mp3' });
      this.mp3File = new File([mp3DataBlob], 'recorded_audio.mp3', { type: 'audio/mp3' });
    },
    uploadFile() {
      const formData = new FormData();
      formData.append('audio', this.mp3File);
      uni.uploadFile({
        url: 'http://your-django-server/upload/',
        filePath: this.mp3File.path,
        name: 'audio',
        formData: formData,
        success: (res) => {
          console.log('File uploaded:', res);
        },
        fail: (error) => {
          console.error('Error uploading file:', error);
        },
      });
    },
  },
};
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.waveform {
  width: 300px;
  height: 100px;
  background-color: #f0f0f0;
}

.controls {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

button {
  margin: 0 10px;
}
</style>

请确保在uniapp项目中安装了lamejs库,可以使用以下命令进行安装:

 
npm install lamejs

在Django服务器端,你需要修改视图函数来处理MP3文件的上传和保存。以下是一个简单的示例代码:

 
  • from django.http import JsonResponse
    
    def upload_file(request):
        if request.method == 'POST' and request.FILES.get('audio'):
            audio_file = request.FILES['audio']
            with open('path/to/save/audio.mp3', 'wb') as f:
                for chunk in audio_file.chunks():
                    f.write(chunk)
            return JsonResponse({'success': True})
        return JsonResponse({'success': False, 'message': 'Invalid request'})
    

    请将上述代码保存为一个Django视图函数,并将其添加到你的Django项目的URL配置中。

    注意:上述代码仅为示例,你可能需要根据你的具体需求进行适当的修改和调整。

  • npm install lamejs 下载不下来
  • 如果你无法通过npm install lamejs命令下载lamejs库,可能是由于网络问题或库的可用性问题。你可以尝试以下解决方案:

    1. 使用淘宝镜像:在命令行中执行以下命令,将npm的镜像源切换为淘宝镜像,然后再次尝试安装:

       
  • npm config set registry https://registry.npm.taobao.org
    
  • 使用cnpm:cnpm是淘宝镜像提供的npm镜像的命令行工具,可以尝试使用cnpm来安装:

     
    1. npm install -g cnpm --registry=https://registry.npm.taobao.org
      cnpm install lamejs
      
    2. 手动下载:如果以上方法仍然无法下载,你可以尝试手动下载lamejs库的压缩包。你可以在https://www.npmjs.com/package/lamejs上找到lamejs的页面,然后下载最新版本的压缩包。下载完成后,解压缩并将其中的文件复制到你的uniapp项目中的合适位置。

    请注意,以上解决方案仅供参考,具体的操作可能因个人环境和网络条件而有所不同。如果问题仍然存在,请尝试在其他网络环境下进行安装,或者考虑使用其他类似的库来处理音频文件的转换。

  • npm ERR! code CERT_HAS_EXPIRED
    npm ERR! errno CERT_HAS_EXPIRED
    npm ERR! request to https://registry.npm.taobao.org/cnpm failed, reason: certificate has expired
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     C:\Users\Administrator\AppData\Local\npm-cache\_logs\2024-01-25T09_21_52_636Z-debug-0.log
  • 这个错误提示表明你的npm证书已过期,导致无法从https://registry.npm.taobao.org下载lamejs库。你可以尝试以下解决方案:

    1. 更新npm:运行以下命令来更新npm到最新版本:

       
  • npm install -g npm
    
  • 清除npm缓存:运行以下命令来清除npm缓存:

     
  • npm cache clean --force
    
  • 使用其他镜像源:尝试使用其他npm镜像源来安装lamejs。你可以尝试使用npm的官方镜像源或其他可靠的镜像源。运行以下命令来切换镜像源:

     
  • npm config set registry https://registry.npmjs.org/
    
  • 使用代理:如果你在使用代理服务器,请确保npm配置了正确的代理设置。你可以通过运行以下命令来配置代理:

     
    1. npm config set proxy http://your-proxy-server:port
      npm config set https-proxy http://your-proxy-server:port
      

    如果以上解决方案仍然无法解决问题,可能是由于网络或其他环境问题导致的。你可以尝试在其他网络环境下进行安装,或者考虑使用其他类似的库来处理音频文件的转换。

这里笔者使用手动下载的方式

要手动下载lamejs到UniApp项目中,可以按照以下步骤进行操作:

  1. 打开lamejs的GitHub页面:https://github.com/zhuker/lamejs

  2. 在页面上找到并点击绿色的 “Code” 按钮,然后选择 “Download ZIP” 下载lamejs的源代码压缩包。

  3. 解压下载的ZIP文件,得到一个名为 “lamejs-master” 的文件夹。

  4. 打开你的UniApp项目,在项目的根目录下找到 “static” 文件夹(如果没有则手动创建一个)。

  5. 将解压得到的 “lamejs-master” 文件夹复制到 “static” 文件夹中。

  6. 在你的UniApp项目中,找到需要使用lamejs的页面或组件。

  7. 在需要使用lamejs的页面或组件中,使用相对路径引入lamejs的相关文件。例如,如果你在页面的script标签中引入lamejs,可以使用以下代码:

 
  • import lamejs from '@/static/lamejs-master/lame.min.js';
    
    1. 现在你可以在页面或组件中使用lamejs的功能了。

    请注意,以上步骤假设你已经安装了UniApp开发环境,并且已经创建了一个UniApp项目。如果你的项目结构有所不同,你需要根据实际情况进行相应的调整。

lamejs (v1.2.1) - Pure JavaScript MP3 Encoder | BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1410587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

binary_search_tree的介绍与实现(二叉搜索树精美图示详解哦)

二叉搜搜索树 引言二叉搜索树的介绍二叉搜索树的实现框架默认成员函数构造析构赋值重载 InsertR&#xff08;插入&#xff09;EraseR&#xff08;删除&#xff09;SearchR&#xff08;查找&#xff09; 源码概览总结 引言 在C语言部分&#xff0c;我们已经认识了树与二叉树的结…

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c;包括 CPU、内存、磁盘三大方面&#xff0c; 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写&#xff0c;是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…

Linux文件管理技术实践

shell shell的种类(了解) shell是用于和Linux内核进行交互的一个程序&#xff0c;他的功能和window系统下的cmd是一样的。而且shell的种类也有很多常见的有c shell、bash shell、Korn shell等等。而本文就是使用Linux最常见的bash shell对Linux常见指令展开探讨。 内置shell…

【大模型研究】(1):从零开始部署书生·浦语2-20B大模型,使用fastchat和webui部署测试,autodl申请2张显卡,占用显存40G可以运行

1&#xff0c;演示视频 https://www.bilibili.com/video/BV1pT4y1h7Af/ 【大模型研究】&#xff08;1&#xff09;&#xff1a;从零开始部署书生浦语2-20B大模型&#xff0c;使用fastchat和webui部署测试&#xff0c;autodl申请2张显卡&#xff0c;占用显存40G可以运行 2&…

重磅!证监会回应股市波动!2万亿元救市计划正在商榷!将提振比特币?

最近这段时间&#xff0c;国内资本市场震荡走弱、波动加大&#xff0c;一些投资者深感忧虑。多家机构表示&#xff0c;市场波动已引起高层的重视。 继1月23日&#xff0c;证监会党委扩大会议从宏观层面提出资本市场建设发力重点后&#xff0c;1月24日证监会副主席王建军的一席采…

工作软技能第一弹,关于职场沟通、成长的那些事

引言 在谈绩效后&#xff0c;我收获了一些心得&#xff0c;在此梳理出来&#xff0c;加深印象并且共勉 基本信息 在步入职场后&#xff0c;你可能跟我一样虽然技术水平有在上升&#xff0c;但是在处理一些事情上可能偶尔没能获得预期的成果。我在通过绩效沟通以及自我反思后…

centos系统安装Ward服务器监控工具

简介 Ward是一个简约美观多系统支持的服务器监控面板 安装 1.首先安装jdk yum install java-1.8.0-openjdk-devel.x86_64 2.下载jar wget 3.启动 java -jar ward-1.8.8.jar 体验 浏览器输入 http://192.168.168.110:4000/ 设置服务名设置为:myserver 端口号:5000 点击…

php实现多进程的几种方式

目录 一&#xff1a;使用pcntl扩展库 二&#xff1a;使用Swoole扩展 三&#xff1a;使用多进程模式PHP-FPM 在PHP中实现多进程主要有以下几种方式&#xff1a; 一&#xff1a;使用pcntl扩展库 pcntl扩展库提供了多线程相关的函数&#xff0c;如pcntl_fork()用于创建子进程…

探索设计模式的魅力:深入理解面向对象设计的深层原则与思维

如何同时提高一个软件系统的可维护性 和 可复用性是面向对象对象要解决的核心问题。 通过学习和应用设计模式&#xff0c;可以更加深入地理解面向对象的设计理念&#xff0c;从而帮助设计师改善自己的系统设计。但是&#xff0c;设计模式并不能够提供具有普遍性的设计指导原则。…

C#用DateAndTime.DateDiff方法和TimeSpan分别计算时间间隔

目录 一、计算时间间隔的方法 1.用DateAndTime.DateDiff方法计算时间间隔 2.使用TimeSpan获取日期时间间隔 二、实例 1.示例一&#xff1a;用DateAndTime.DateDiff方法计算时间间隔 2.示例二&#xff1a;使用TimeSpan获取日期时间间隔 一、计算时间间隔的方法 1.用Date…

vue3 组件通信 mitt

mitt 安装 pnpm add mitttypescript 在 tsconfig.json 中设置 “strict”: true {"compilerOptions": {"strict": true,} }使用 导出 emitter src/utils/mitt/index.ts import mitt from mitttype Events {get-name: string }export const emitter …

go-zero 统一返回

1、整体目录结构 1、全局处理主入口 package manageimport ("net/http""github.com/zeromicro/go-zero/rest/httpx" )type Body struct {Code int json:"code"Message string json:"message"Result interface{} jso…

每日一道Java面试题:方法重载与方法重写,这把指定让你明明白白!

写在开头 请聊一聊Java中方法的重写和重载&#xff1f; 这个问题应该是各大厂面试时问的最多的话题之一了&#xff0c;它们几乎贯穿了我们日常的开发工作&#xff0c;在过往的博客中我们多多少少都提到过重载与重写&#xff0c;而今天我们就一起来详细的学习一下这二者的功能与…

arcgis实现截图/截屏功能

arcgis实现截图/截屏功能 文章目录 arcgis实现截图/截屏功能前言效果展示相关代码 前言 本篇将使用arcgis实现截图/截屏功能&#xff0c;类似于qq截图 效果展示 相关代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta nam…

InnoDB索引

B树与B树 索引的数据结构就是B树&#xff0c;它的叶子节点存储数据(数据页)&#xff0c;非叶子节点存储索引(索引页)。 所以索引走树&#xff0c;全表扫走叶子节点的单向链表(mysql里优化成双向) 二级索引页(非主键) 多个目录项记录 目录项记录 每页记录的最小值 主键值 …

Linux系统下常用软件安装汇总,包括mysql,java,git,redis等

01.环境搭建 1.安装列表 MySQL 5.7.11 Java 1.8 Apache Maven 3.6 tomcat8.5 git Redis Nginx python docker 2.安装mysql 1.拷贝mysql安装文件到Linux的某个目录下 2.解压Linux安装包&#xff1a;tar -xvzf mysql-5.7.32-linux-glibc2.12-x86_64.tar.gz 3.进入解压后…

[漏洞复现]Redis 沙盒逃逸漏洞(CVE-2022-0543)

一、漏洞情况分析 Redis 存在代码注入漏洞&#xff0c;攻击者可利用该漏洞远程执行代码。 二、漏洞复现 春秋云境.com 进入靶场 开始复现 三、漏洞处置建议 把靶场关了&#xff0c;跟漏洞说“白白吧

4.【SpringBoot3】文章管理接口开发

序言 在文章管理模块&#xff0c;有以下接口需要开发&#xff1a; 新增文章文章列表&#xff08;条件分页&#xff09;获取文章详情更新文章删除文章 数据库表字段和实体类属性&#xff1a; 1. 新增文章 需求分析 当用户点击左侧菜单中的“文章管理”后&#xff0c;页面主…

apk加固后,签名后没有V2签名的,targetsdk版本改为30后报字节没有对齐的

当我吧targetsdk版本改为30后,加固后重新签名发现,安装不上报错 adb: failed to install E:\XX\262_rel.apk: Failure [-124: Failed parse during installPackageLI: Targeting R (version 30 and above) requires the resources.arsc of installed APKs to be stored uncomp…

全桥变压器计算1

一共有两级&#xff0c;先DC升压&#xff0c;后H桥逆变为AC 因为两级都有损耗&#xff0c;所以一般用输入功率计算 电池升压到400V高压用的效率用表示&#xff0c;后面DC转AC的效率用表示&#xff0c;输入电压用Vin&#xff0c;输出功率Po2000W,输入功率为Pin 一般和96% 所…