【问题标题】:How can I get recorded video from js to my Flask App?如何将录制的视频从 js 获取到我的 Flask 应用程序?
【发布时间】:2021-01-11 20:50:43
【问题描述】:

我有一个烧瓶应用程序,它应该录制视频并能够将该视频发送回我的 python 脚本,然后放入数据库中。 我试图将它放入一个表格中,但不太确定我是否以正确的方式进行操作。 这是我的js

  audio: false, 
  video:true
}; 

if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
  navigator.mediaDevices.getUserMedia = function(constraintObj) {
      let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
      if (!getUserMedia) {
          return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
      }
      return new Promise(function(resolve, reject) {
          getUserMedia.call(navigator, constraintObj, resolve, reject);
      });
  }
}else{
  navigator.mediaDevices.enumerateDevices()
  .then(devices => {
      devices.forEach(device=>{
          console.log(device.kind.toUpperCase(), device.label);
          //, device.deviceId
      })
  })
  .catch(err=>{
      console.log(err.name, err.message);
  })
}

navigator.mediaDevices.getUserMedia(constraintObj)
.then(function(mediaStreamObj) {
  //connect the media stream to the first video element
  let video = document.querySelector('video');
  if ("srcObject" in video) {
      video.srcObject = mediaStreamObj;
  } else {
      //old version
      video.src = window.URL.createObjectURL(mediaStreamObj);
  }
  
  video.onloadedmetadata = function(ev) {
      //show in the video element what is being captured by the webcam
      video.play();
  };
  let start = document.getElementById('startbtn');
  let stop = document.getElementById('btnStop');
  let vidSave = document.getElementById('vid2');
  let mediaRecorder = new MediaRecorder(mediaStreamObj);
  let chunks = [];
  
  start.addEventListener('click', (ev)=>{
      mediaRecorder.start();
      console.log(mediaRecorder.state);
  })
  stop.addEventListener('click', (ev)=>{
      mediaRecorder.stop();
      console.log(mediaRecorder.state);
  });
  mediaRecorder.ondataavailable = function(ev) {
      chunks.push(ev.data);
  }
  mediaRecorder.onstop = (ev)=>{
      let blob = new Blob(chunks, { 'type' : 'video/mp4;' });
      for (chunk in chunks) {
        console.log(chunk);
      }
      chunks = [];
      let videoURL = window.URL.createObjectURL(blob);
      vidSave.src = videoURL;
  }
  $.post('/video',
  {share: videoURL}, function(data) {

  })
})
});

以及我在烧瓶应用中的路线

@main_bp.route('/video' , methods=['GET', 'POST'])
@login_required
def video():
    form = VideoForm()
    if form.validate_on_submit():
        flash('Video Saved Successfully!')
        vid = request.json['share']
        print(jsonify(vid))
        return redirect('home.html')
    return render_template('video.html', form=form, name=current_user.username)```

我也有一个 VideoForm 类,因为我一直将它用于我的登录表单,但我不确定视频以何种方式返回给我,例如 json、图像等。 这是 VideoForm

class VideoForm(FlaskForm):
    video = FileField('img')
    submit = SubmitField('Save Video')

如果有人知道如何或有任何提示可以为我指明正确的方向,那至少会很棒! 谢谢

【问题讨论】:

    标签: flask getusermedia


    【解决方案1】:

    您可以使用“multipart/form-data”类型的表单来传输视频。
    使用此变体,可以在烧瓶中以文件 (werkzeug.FileStorage) 的形式访问数据。

    let formData = new FormData();
    formData.append('video', blob, "video.mp4");
    $.ajax ({
      url: "/upload",
      type: "POST",
      data: formData,
      processData: false,
      contentType: false,
      success: function(resp){
        console.log(resp);
      }
    });
    
    @app.route('/upload', methods=['POST'])
    def upload():
        video = request.files.get('video')
        if video: 
              
           # process the file object here! 
    
           return jsonify(success=True)
        return jsonify(success=False)
    

    作为一种简单的替代方法,您还可以将数据以原始格式发送到服务器。
    在这种情况下,数据会填充整个帖子正文,可以作为一个整体加载,也可以从流中加载 (werkzeug.LimitedStream)。

    $.ajax ({
      url: "/upload",
      type: "POST",
      data: blob,
      contentType: "video/mp4",
      processData: false,
      success: function(resp){
        console.log(resp);
      }
    });
    
    @app.route('/upload', methods=['POST'])
    def upload():
        if request.headers.get('Content-Type') == 'video/mp4':
            # load the full request data into memory
            # rawdata = request.get_data()
            
            # or use the stream 
            rawdata = request.stream.read()
    
            # process the data here!
    
            return jsonify(success=True)
        return jsonify(success=False)
    

    【讨论】:

    • 非常感谢!我最终在您的第一个回答中使用了video = request.files['video'] ,您知道为什么它需要转到/upload 而不能只添加到/video 吗?跨度>
    • 它也可以添加到/video,但是你必须使用request.method来区分GET和POST。就个人而言,我喜欢将返回 json 的路由与以 html 格式回复的路由分开。如果出现错误,您可以将蓝图与abort 结合使用,然后以相应的格式回复。注册error handlers受蓝图限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 2013-07-08
    • 2012-04-24
    相关资源
    最近更新 更多