• 通过flash+js 实现web中录音 FlashWavRecorder


    最近在做一个小网站,其中有一个语音识别的功能,我暂时打算用Google Speech API来实现,但是在这之前还有一个小问题那就是录音。要在网页中录音应该大多数是通过Flash或者java applet实现的,因为考虑到flash比较普及,我觉得采用flash。因为我本身不会flash actionscript那些,想在网上找个现成,功夫不负有心人终于让我找到了这个FlashWavRecorder。其github地址为:https://github.com/cykod/FlashWavRecorder

    这个项目你一个有两文件夹flash和html,flash文件夹中是文件,html文件夹中是一个示例,试了一下果然能录音。
    但是上传却出了问题,卡在save_progress了。

    找了一会儿原因,发现是接受上传文件的upload.php有个小问题,他的<? 后面没有php导致直接把所有代码当文本返回了。改完之后如下:

    <?php
    $save_folder = dirname(__FILE__) . "/audio";
    if(! file_exists($save_folder)) {
      if(! mkdir($save_folder)) {

    首先下面的配置对我来说并不需要,我把它直接删了,但是问题就出现了。

     

    发生这个问题的原因是index.html 中有一段js脚本

    $(function() {
      var gain = $('#gain')[0];
      var silenceLevel = $('#silenceLevel')[0];
      for(var i=0; i<=100; i++) {
        gain.options[gain.options.length] = new Option(100-i);
        silenceLevel.options[silenceLevel.options.length] = new Option(i);
      }
    
      var appWidth = 24;
      var appHeight = 24;
      var flashvars = {'event_handler': 'microphone_recorder_events', 'upload_image': 'images/upload.png'};
      var params = {};
      var attributes = {'id': "recorderApp", 'name':  "recorderApp"};
      swfobject.embedSWF("recorder.swf", "flashcontent", appWidth, appHeight, "11.0.0", "", flashvars, params, attributes);
    });

    因为我把配置的表单删掉了,所以$(‘#gain’)[0]和$(‘#silenceLevel’)[0]都是undefined的,对它们进行操作报错脚本终止导致flash没有成功加载,把那下面这5行删掉即可。

      var gain = $('#gain')[0];
      var silenceLevel = $('#silenceLevel')[0];
      for(var i=0; i<=100; i++) {
        gain.options[gain.options.length] = new Option(100-i);
        silenceLevel.options[silenceLevel.options.length] = new Option(i);
      }

    总的来说这个东西就是js调用flash的js接口,flash里再调用js与页面交互。

    位于recorder.js文件的microphone_recorder_events函数就是处理flash返回状态的函数。
    通过修改这个函数可以修改flash不同状态事页面的显示。

    因为这个flash每次刷新页面后都要点一下录音按键后允许flash使用麦克风才行,我想省掉要先点录音按键这一步,页面刷新有自动弹出麦克风请求窗口。其实只要还microphone_recorder_events中case “ready” 这个分支的最后加一行Recorder.record(‘audio’, ‘audio.wav’);即可,因为点击那个红色的录音键实际上也是执行了这句脚本。

     case "ready":
        var width = parseInt(arguments[1]);
        var height = parseInt(arguments[2]);
        Recorder.uploadFormId = "#uploadForm";
        Recorder.uploadFieldName = "upload_file[filename]";
        Recorder.connect("recorderApp", 0);
        Recorder.recorderOriginalWidth = width;
        Recorder.recorderOriginalHeight = height;
        $('#play_button').css({'margin-left': width + 8});
        $('#save_button').css({'width': width, 'height': height});
        Recorder.record('audio', 'audio.wav'); //在示例中改成$("#record_button").click();也行
      break;

    最后我想实现停止录音后直接上传该怎么修改呢?

    这个上传按键并不是一个html元素,而是在flash中的,这意味着我不得不去修改flash了。

    flash文件夹下有4个as文件,因为只是要改一小点我就直接看RecorderJSInterface.as这个文件了,果然和文件名一样这个文件定义了js调用的入口,还有通过ExternalInterface.call(methodName: String, [parameter1: Object]) : Object 方法调用页面中的js。

    话不多说,我在这个文件中找到两个关键的方法record(name:String, filename:String=null):Boolean 和 save():Boolean 一个是录音是调用的,第二个是保存(就是上传服务器)时调用的。这样在record中停止录音的语句后调用sava方法即可,修改后如下:

        public function record(name:String, filename:String=null):Boolean {
          if(! this.isMicrophoneAvailable()) {
            return false;
          }
    
          if(this.recorder.recording) {
            this.recorder.stop();
            ExternalInterface.call(this.eventHandler, RecorderJSInterface.RECORDING_STOPPED, this.recorder.currentSoundName, this.recorder.duration());
            this.save();   //加入这句
          } else {
            this.recorder.record(name, filename);
            ExternalInterface.call(this.eventHandler, RecorderJSInterface.RECORDING, this.recorder.currentSoundName);
          }
    
          return this.recorder.recording;
        }

    接下来就是编译它了,先去下载sdk,下载地址为http://www.adobe.com/devnet/flex/flex-sdk-download-all.html

    下载完成后把其中的bin目录加入环境变量PATH,打开命令行到刚刚的flash目录执行下面语句。

    mxmlc Recorder.as -output recorder.swf

    把生成的recorder.swf覆盖html中的,刷新页面,虽然停止录音后进行了保存但是出现了异常

    但是再点击上传按钮却能成功上传,我检查代码,发现是执行URLLoader.load(request:URLRequest):void时发生了异常,推测是出于安全问题,只能通过用户交互来调用。那我们就来再改一下吧。

    先把recorder.as里的ready方法和save()方法改一下,改成下面这样:

       public function ready():void {
          addChild(saveButton);
    
          recorderInterface.saveButton = saveButton;
    
          saveButton.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
    
          recorderInterface.ready(saveButton.width, saveButton.height);
        }
    
        public function save():void {
          recorderInterface.record("audio", "audio.wav");
        }

    再把RecorderJSInterface.as里show()和hide()方法的函数体变成空的,如下:

        public function show():void {
    
        }
        public function hide():void {
    
        }

    再编译一下搞定,直接点上传键就录音加上传一条龙了。

  • 相关阅读:
    Vue官方脚手架分环境打包配置及接口环境切换
    JS超全判断终端
    H5与APP(安卓及IOS)交互方法
    json数据扁平化处理(适用于接口传参复杂数据加密处理)
    VUE实践经典记录(持续更新)
    Javascript 词法分析
    三栏自适应布局
    前端神器 Firebug 2.0 新特性一览
    事件绑定(终极版)
    正则表达式(下)
  • 原文地址:https://www.cnblogs.com/ksx123/p/3213895.html
Copyright © 2020-2023  润新知