Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用Librosa从blob中提取特征

用Librosa从blob中提取特征
EN

Stack Overflow用户
提问于 2022-01-19 08:27:56
回答 1查看 153关注 0票数 0

我正试图在前端记录一条语音信息,并将其发送到Django后端,以便根据语音性别识别的ML算法对其进行测试。在前端,我使用视频to记录记录声音,并使用AJAX将blob发送到后端,如下所示:

代码语言:javascript
运行
AI代码解释
复制
{% extends 'base.html' %}

{% load static %}

{% block title %}Voice Detector{% endblock %}

{% block extracss %}
<link href="{% static 'css/voice_detector.css' %}" rel="stylesheet" />
<link href="{% static 'css/video-js.css' %}" rel="stylesheet" />
<link href="{% static 'css/all.min.css' %}" rel="stylesheet" />
<link href="{% static 'css/videojs.wavesurfer.min.css' %}" rel="stylesheet" />
<link href="{% static 'css/videojs.record.css' %}" rel="stylesheet" />
{% endblock %}

{% block content %}
<div class="banner">
  <div class="max-width">
    <div class="banner-content">
      <p class="motto">Test your voice right now!</p>
      <p class="description">
        Register your voice while reading the text below and our program will
        detect your gender in a few seconds!
      </p>
    </div>
  </div>
</div>
<div class="details">
  <section class="section">
    <div class="container">
      <div class="columns">
        <div class="column is-offset-4 is-4">
          <h1 class="title">Record audio</h1>
          <article class="message is-success" id="alert">
            <div class="message-header">
              <p>Recorded successfully!</p>
              <button class="delete" aria-label="delete"></button>
            </div>
            <div class="message-body">
              You have successfully recorded your message. You can now click on
              the Submit button to post it.
            </div>
          </article>
          <div class="field">
            <div
              class="control has-icons-left has-icons-right"
              style="margin-top: 1rem"
            >
              <audio
                id="recordAudio"
                class="video-js vjs-default-skin"
              ></audio>
            </div>
            <div class="control" style="margin-top: 1rem">
              <button class="home-btn" id="submit" disabled>Submit</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>
</div>
{% endblock %}

{% block extrajs %}
<script src="{% static 'js/video.min.js' %}"></script>
<script src="{% static 'js/RecordRTC.js' %}"></script>
<script src="{% static 'js/adapter-latest.js' %}"></script>
<script src="{% static 'js/wavesurfer.js' %}"></script>
<script src="{% static 'js/wavesurfer.microphone.min.js' %}"></script>
<script src="{% static 'js/videojs.wavesurfer.min.js' %}"></script>
<script src="{% static 'js/videojs.record.min.js' %}"></script>
<script src="{% static 'js/browser-workaround.js' %}"></script>
<script>
    // First lets hide the message
document.getElementById("alert").style.display = "none";
// Next, declare the options that will passed into the recording constructor
const options = {
  controls: true,
  bigPlayButton: false,
  width: 600,
  height: 300,
  fluid: true, // this ensures that it's responsive
  plugins: {
    wavesurfer: {
      backend: "WebAudio",
      waveColor: "#f7fff7", // change the wave color here. Background color was set in the css above
      progressColor: "#ffe66d",
      displayMilliseconds: true,
      debug: true,
      cursorWidth: 1,
      hideScrollbar: true,
      plugins: [
        // enable microphone plugin
        WaveSurfer.microphone.create({
          bufferSize: 4096,
          numberOfInputChannels: 1,
          numberOfOutputChannels: 1,
          constraints: {
            video: false,
            audio: true,
          },
        }),
      ],
    },
    record: {
      audio: true, // only audio is turned on
      video: false, // you can turn this on as well if you prefer video recording.
      maxLength: 180, // how long do you want the recording?
      displayMilliseconds: true,
      debug: true,
    },
  },
};

// apply audio workarounds for certain browsers
applyAudioWorkaround();

// create player and pass the the audio id we created then
var player = videojs("recordAudio", options, function () {
  // print version information at startup
  var msg =
    "Using video.js " +
    videojs.VERSION +
    " with videojs-record " +
    videojs.getPluginVersion("record") +
    ", videojs-wavesurfer " +
    videojs.getPluginVersion("wavesurfer") +
    ", wavesurfer.js " +
    WaveSurfer.VERSION +
    " and recordrtc " +
    RecordRTC.version;
  videojs.log(msg);
});

// error handling
player.on("deviceError", function () {
  console.log("device error:", player.deviceErrorCode);
});

player.on("error", function (element, error) {
  console.error(error);
});

// user clicked the record button and started recording
player.on("startRecord", function () {
  console.log("started recording!");

  $("#submit").prop("disabled", true);
});

// user completed recording and stream is available
player.on("finishRecord", function () {
  const audioFile = player.recordedData;

  console.log("finished recording: ", audioFile);

  $("#submit").prop("disabled", false);
  document.getElementById("alert").style.display = "block";
});

// Give event listener to the submit button
$("#submit").on("click", function (event) {
  event.preventDefault();
  let btn = $(this);
  //   change the button text and disable it
  btn.html("Submitting...").prop("disabled", true).addClass("disable-btn");
  //   create a new File with the recordedData and its name
  const recordedFile = new File([player.recordedData], `test.wav`);
  //   initializes an empty FormData
  let data = new FormData();
  //   appends the recorded file and language value
  data.append("file", recordedFile);

  //   post url endpoint
  $.ajax({
    url: "{% url 'detector' %}",
    method: "POST",
    data: data,
    dataType: "json",
    success: function (response) {
      if (response.success) {
        document.getElementById("alert").style.display = "block";
        window.location.href = `${response.url}`;
      } else {
        btn.html("Error").prop("disabled", false);
      }
    },
    error: function (error) {
      console.error(error);
    },
    cache: false,
    processData: false,
    contentType: false,
  });
});
</script>
{% endblock %}

在后端,我尝试使用wave将文件保存为有效的.wav,如下所示:

代码语言:javascript
运行
AI代码解释
复制
def post(self, request):
        f = request.FILES['file']

        with open('file.wav', 'wb+') as destination:
            for chunk in f.chunks():
                destination.write(chunk)

        with open('file.wav', 'rb') as file:
            file_content = file.read()
            audio = wave.open('test.wav', 'wb')
            audio.setnchannels(1)
            audio.setnframes(1)
            audio.setsampwidth(1)
            audio.setframerate(8000)
            audio.writeframes(file_content)
            audio.close()

        (prediction, probability) = predict('test.wav')

        context["prediction"] = prediction
        context["probability"] = probability*100

        os.remove(file_name)

        return render(request, self.template_name, context=context)

在这里,我试了两样东西。第一次尝试是使用“wb”打开将blob直接保存到文件中。这个方法的问题是librosa抱怨文件类型不被识别。另一个尝试是用wave,但是不管我尝试什么,用wave保存的文件都会产生噪声,而预测算法失败了。下面是我想使用带有录音声音的文件来进行预测的方法:

代码语言:javascript
运行
AI代码解释
复制
def predict(file_name):
    # construct the model
    model = create_model()

    # load the saved/trained weights
    model.load_weights('model.h5')

    # extract features and reshape it
    features = extract_feature(file_name, mel=True).reshape(1, -1)

    # predict the gender!
    male_prob = model.predict(features)[0][0]
    female_prob = 1 - male_prob

    gender = "male" if male_prob > female_prob else "female"

    if gender == "male":
        return (gender, male_prob)

    return (gender, female_prob)

下面是extract_feature函数,我在其中加载并处理该文件:

代码语言:javascript
运行
AI代码解释
复制
def extract_feature(file_name, **kwargs):
    mfcc = kwargs.get("mfcc")
    chroma = kwargs.get("chroma")
    mel = kwargs.get("mel")
    contrast = kwargs.get("contrast")
    tonnetz = kwargs.get("tonnetz")
    X, sample_rate = librosa.core.load(file_name)

    if chroma or contrast:
        stft = np.abs(librosa.stft(X))

    result = np.array([])

    if mfcc:
        mfccs = np.mean(librosa.feature.mfcc(y=X, sr=sample_rate, n_mfcc=40).T, axis=0)
        result = np.hstack((result, mfccs))

    if chroma:
        chroma = np.mean(librosa.feature.chroma_stft(S=stft, sr=sample_rate).T,axis=0)
        result = np.hstack((result, chroma))

    if mel:
        mel = np.mean(librosa.feature.melspectrogram(X, sr=sample_rate).T,axis=0)
        result = np.hstack((result, mel))

    if contrast:
        contrast = np.mean(librosa.feature.spectral_contrast(S=stft, sr=sample_rate).T,axis=0)
        result = np.hstack((result, contrast))

    if tonnetz:
        tonnetz = np.mean(librosa.feature.tonnetz(y=librosa.effects.harmonic(X), sr=sample_rate).T,axis=0)
        result = np.hstack((result, tonnetz))

    return result

我做错了什么?是否有一种方法可以创建一个有效的WAV文件,其内容与我在前端记录的blob相同?还是有一种方法可以直接使用我从前面收到的blob?

EN

回答 1

Stack Overflow用户

发布于 2022-01-19 09:47:21

经过深入研究,我在Linux上发现了ffmpeg工具,并在python中使用它将文件从WebM格式转换为WAV。以下是解决办法:

代码语言:javascript
运行
AI代码解释
复制
def post(self, request):
        webm_file = str(datetime.datetime.now()) + ".webm"
        wav_file = str(datetime.datetime.now()) + ".wav"

        f = request.FILES['file']

        with open(webm_file, 'wb+') as destination:
            for chunk in f.chunks():
                destination.write(chunk)
            destination.close()

        # convert file from WebM to WAV format
        subprocess.run(["ffmpeg", "-i", webm_file, "-vn", wav_file])

        (prediction, probability) = predict(wav_file)

        context["prediction"] = prediction
        context["probability"] = probability*100

        os.remove(webm_file)
        os.remove(wav_file)

        return render(request, self.template_name, context=context)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70774251

复制
相关文章
EasyCVR平台出现部分设备播放正常部分设备视频无法播放,是什么原因?
EasyCVR视频融合平台支持多种协议、多种类型的设备接入,拥有灵活丰富的视频能力,可提供视频直播、转码与分发、级联、云台控制等,平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在线下具有广泛的应用场景。
TSINGSEE青犀视频
2022/09/20
1990
EasyDSS平台其他协议的视频可正常播放,WebRTC却无法播放是什么原因?
EasyDSS视频直播点播平台集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体,可提供音视频采集、视频推拉流、播放H.265编码视频、存储,分发的视频流可覆盖全终端、全平台。
TSINGSEE青犀视频
2022/09/09
5180
jqm视频播放器,html5视频播放器,html5音乐播放器,html5播放器,video开发demo,html5视频播放示例,html5手机视频播放器
最近在论坛中看到了很多实用html5开发视频播放,音乐播放的功能,大部分都在寻找答案。因此我就在这里做一个demo,供大家相互学习。html5开发越来越流行了,而对于视频这一块也是必不可少的一部分。如何让你的网站占据优势,就要看你的功能和用户体验了。html5对video还是做了很多优惠的东西,我们使用起来很得心应手。 在过去 flash 是网页上最好的解决视频的方法,截至到目前还算是主流,像那些优酷之类的视频网站、虾米那样的在线音乐网站,仍然使用 flash 来提供播放服务。但是这种状况将会随着 HTML5 的发展而改变。就视频而言,HTML5 新增了 video 来实现在线播放视频的功能。 使用 HTML5 的 video 可以很方便的使用 JavaScript 对视频内容进行控制等等,功能十分强大,同时代码比较少加快加载速度。此外跨平台性比较好,特别是一些平板、手机等。例如苹果公司的产品不支持 flash 仅支持 HTML5 中的 video 功能。 HTML5 的兼容性问题虽然目前是个硬伤,但这只是时间的问题。好吧废话少说,看代码:
业余草
2019/01/21
6.6K0
jqm视频播放器,html5视频播放器,html5音乐播放器,html5播放器,video开发demo,html5视频播放示例,html5手机视频播放器
EasyCVR平台通道视频正常播放,但设备录像却无法播放是什么原因?
EasyCVR是集视频互联网、存储、流媒体转发、视频转码、智能分析等多功能为一体的流媒体视频服务融合平台。平台基于云边端一体化架构,兼容性高、拓展性强,可支持多类型设备、多协议方式接入,包括国标GB/T28181、RTMP、RTSP/Onvif协议,以及厂家的私有协议,如:海康Ehome协议、海康SDK、大华SDK等。在功能上,EasyCVR可支持云端录像回看以及设备录像回看。
TSINGSEE青犀视频
2022/10/21
3350
iOS 视频播放方式整理
初衷 ----       多媒体这整个系列的文章自己也准备好开始整理了,先从视频音频最简单也是最常用的播放出发慢慢的往下深究,探索到底层的编码解码等等,这篇文章就从视频的播放这个最简单的说起。       iOS的视频播放方式有几种?其实要是只是简单的想播放一段视频并且对UI没什么要求的话的确比较简单,很容易搞定,但我相信这种情况除了你的Demo一般是不会出现的,对播放UI的定义以及可能有各种不同的需求对应着你是不能随便写个播放器就没事了的。 最原始的播放 ----       要不是刚接触iOS开发的同
Mr.RisingSun
2018/02/06
2.7K0
iOS 视频播放方式整理
iOS简单的视频播放
导入 MediaPlayer.framework - (void)viewDidLoad { [super viewDidLoad]; NSString* path = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp4"]; NSURL* url = [NSURL fileURLWithPath:path]; _playerController = [[MPMoviePlayerViewController alloc] in
用户8671053
2021/10/29
5720
EasyCVR视频融合平台能正常播放其他协议流,但无法播放HLS流的原因排查
EasyCVR基于云边端一体化架构,支持海量视频汇聚管理,平台支持多协议与多类型设备接入,具体包括国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等,能对外分发RTMP、RTSP、HTTP-FLV、WS-FLV、HLS、WebRTC等。
TSINGSEE青犀视频
2023/07/19
1980
EasyCVR接入国标设备后视频直播正常,设备录像无法播放是什么原因?
EasyCVR基于云边端协同,具有强大的数据接入、处理及分发能力,平台可支持海量视频的轻量化接入与汇聚管理,可提供视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联等功能。在录像功能上,平台支持云端录像、设备录像,并能支持检索与回放。
TSINGSEE青犀视频
2023/06/07
2460
EasyGBS平台设备在线视频流也正常,但是为何无法播放?
EasyGBS是基于国标GB28181协议的视频平台,平台可提供流媒体接入、处理、转发等服务,支持内网、公网的监控设备通过国标GB/T28181协议进行视频监控直播。
TSINGSEE青犀视频
2022/03/15
6310
iOS AVPlayer视频播放器
GOVVideoPlayer/GOVVideoController 是一个基于AVPlayer封装的视频播放器,支持播放/暂停、左右退拽快进、上下滑动调节音量、自动手动全屏、全屏时横屏Or竖屏、有缓冲进度指示条、卡顿指示器、切换视频源。 ---- 更新于2017/8/10,增加了GOVVideoController GOVVideoPlayer是在继承于UIView的基础上封装的视频View; GOVVideoController是在继承于UIViewController的基础上封装的视频视图控制器,
且行且珍惜_iOS
2018/05/22
4K0
iOS视频播放的基本方法
本文总结了iOS中最常见的视频播放方法,不同的方法都各具特点,我希望能够总结它们的不同,方便在开发中选择合适的技术方案。 Apple为我们提供了多种方法来实现视频播放,包括MPMoviePlayerController,MPMoviePlayerViewController,AVPlayer,AVPlayerViewController等。而值得注意的是,上述的MPMoviePlayerController与MPMoviePlayerViewController在iOS9.0之后被弃用。虽说如此,这还是将它
梧雨北辰
2018/07/06
4.5K0
Tcplayer 在ios无法正常播放直播流
var player = new TcPlayer('id_test_video', {
用户6942005
2020/12/21
1.9K9
Html5音频和视频播放示例
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>html5中的音频和视频</title> </head> <body> <!--html4中的音频视频播放方式 代码冗杂,加载失败无法播放,一片空白..需要flash支持 --> <object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="500" height
用户7718188
2021/11/01
3K0
EasyCVR新版本(v2.5.0)无法播放WebRTC视频,其他格式均正常播放,是什么原因?
EasyCVR平台基于云边端一体化管理,支持多协议、多类型的视频设备接入,对外可分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。在视频功能上,可提供服务器集群、视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、智能分析等服务。
TSINGSEE青犀视频
2022/08/11
3240
iOS音视频播放(Audio Unit播放音频+OpenGL ES绘制视频)
前言 相关文章: 使用VideoToolbox硬编码H.264 使用VideoToolbox硬解码H.264 使用AudioToolbox编码AAC 使用AudioToolbox播放AAC HLS点播实现(H.264和AAC码流) HLS推流的实现(iOS和OS X系统) iOS在线音频流播放 Audio Unit播放PCM文件 Audio Unit录音(播放伴奏+耳返) Audio Unit播放aac/m4a/mp3等文件 Audio Unit和ExtendedAudioFile播放
落影
2018/04/27
2.6K0
iOS音视频播放(Audio Unit播放音频+OpenGL ES绘制视频)
网页嵌入Bilibili HTML5视频播放
Bilibili好在无广告,速度也挺快,无奈B站官方的视频嵌入是Flash的形式,但B站又是支持HTML5播放的,那么问题来了,外站如何嵌入HTML5的播放形式呢? 参考了这篇文章 http://www.jianshu.com/p/205385febcae ,但这篇文章的问题在于嵌入的视频并非“全屏”,右半边是弹幕什么的东西,这些我们并不需要,需要的仅仅是播放页。 在网页源代码中查找到cid和aid 拼接下面的URL(替换为你的cid和aid) https://player.bilibili.com/pla
许杨淼淼
2018/07/11
10.1K0
HTML5 video视频倍速播放playbackRate
// 视频获取速率 var videoSpeed = video.playbackRate; // 视频设置播放速率,如2倍速播放 video.playbackRate = 2; // 获取音频播放速率 var audioSpeed = audio.playbackRate; // 音频设置播放速率,如2倍速播放 audio.playbackRate = 2; 现在看见没有倍速播放功能的网站,你可以F12打开在控制台更改成自己想要的倍速进行观看了。。。 document.getElementById('#
javascript.shop
2019/09/04
4K0
IOS AVPlayViewController 实现视频播放的控制
1 import UIKit 2 import AVFoundation 3 import AVKit 4 5 class ViewController:UIViewController { 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 // Do any additional setup after loading the view, typically from a nib. 9 let moviePath = Bu
用户5760343
2019/07/08
1.7K0
iframe HTML5视频全屏播放问题
背景:我采用了videojs视频播放器。视频播放页面是一个独立页面 包含了html5播放器代码。 主页面采用iframe 调用视频播放页面。
lilugirl
2019/05/26
6K0
点击加载更多

相似问题

原生mongodb的初步研究

10

MongoDB的GridFS,Rails 3,,和ACL的,如何?

13

如何研究mongodb中的文件结构?

12

Wolkenkit:用于授权和用户角色的ACL

16

返回用户的ACL组

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档