音频和视频还没有合成完成,publish的时候报错 怎么解决

来源:11-16 发布整个视频音频创意(2)

JerseyJerry

2018-03-11

exports.audio = async (ctx, next) =>{

  var body = ctx.request.body

  var audioData = body.audio  // 这个就是 包含public_id等一大坨信息的detail

  var videoId = body.videoId  // 这个是用来指向对应videoId的

  var user = ctx.session.user

  if(!audioData || !audioData.public_id){

    ctx.body = {

      success: false,

      err: 'no audio uploaded to database'

    }

    return

  }

  var audio = await Audio.findOne({

    public_id: audioData.public_id

  })

  var video = await Video.findOne({

    _id: videoId     //看看在video里面能不能找到刚刚上传的video的 public_id

  })

// "secure_url" : "https://res.cloudinary.com/bobolin/video/upload/v1519709188/audio/d0fyjykkatkqqwldlemq.aac",

  if(!audio) {

    var _audio ={

      author: user._id,

      public_id: audioData.public_id,   //"public_id" : "audio/d0fyjykkatkqqwldlemq",

      detail: audioData

    }

 //如果 _id能找到,audio里面增加video参数,值就是video._id;格式是video是ref到Video model(参见audio models里面的定义)

    if(video){

      _audio.video = video._id

    }

    audio = new Audio(_audio) //添加audio collection

    audio = await audio.save()

  }

  //这是异步操作, 会出现,下面的ctx.body 先返回了

  asyncMedia(video._id, audio._id)  //音频保存到databse之后,asyncMedia方法,会合并音频和视频,并且保存到qiniu

  ctx.body ={

    success: true,

    data: audio._id

  }

}


想知道,上面代码中如何让 asyncMedia(video._id, audio._id)完成后,再返回 ctx.body 

我在asyncMedia 前面直接加了await ,也不管用。求教


写回答

3回答

Scott

2018-03-12

改成这样呢试试看


async function asyncMedia (videoId, audioId) {
  if (!videoId) return
  let query = {
    _id: audioId
  }
  if (!audioId) {
    query = {
      video: videoId
    }
  }
  const data = await Promise.all([
    Video.findOne({_id: videoId}),
    Audio.findOne(query)
  ])
  console.log(data)
  const video = data[0]
  const audio = data[1]
  console.log('检查数据有效性')
  if (!video || !video.public_id || !audio || !audio.public_id) {
    return
  }
  console.log('开始同步音频视频')
  const video_public_id = video.public_id
  const audio_public_id = audio.public_id.replace(/\//g, ':')
  const videoName = video_public_id.replace(/\//g, '_') + '.mp4'
  const videoURL = 'http://res.cloudinary.com/gougou/video/upload/e_volume:-100/e_volume:400,l_video:' + audio_public_id + '/' + video_public_id + '.mp4'
  const thumbName = video_public_id.replace(/\//g, '_') + '.jpg'
  const thumbURL = 'http://res.cloudinary.com/gougou/video/upload/' + video_public_id + '.jpg'
  console.log('同步视频到七牛')
  robot
    .saveToQiniu(videoURL, videoName)
    .catch(function(err) {
      console.log(err)
    })
    .then(function(response) {
      if (response && response.key) {
        audio.qiniu_video = response.key
        audio.save().then(function(_audio) {
          Creation.findOne({
            video: video._id,
            audio: audio._id
          })
          .then(function(_creation) {
            if (_creation) {
              if (!_creation.qiniu_video) {
                _creation.qiniu_video = _audio.qiniu_video
                _creation.save()
              }
            }
          })
          console.log(_audio)
          console.log('同步视频成功')
        })
      }
    })
    robot
      .saveToQiniu(thumbURL, thumbName)
      .catch(function(err) {
        console.log(err)
      })
      .then(function(response) {
        if (response && response.key) {
          audio.qiniu_thumb = response.key
          audio.save().then(function(_audio) {
            Creation.findOne({
              video: video._id,
              audio: audio._id
            })
            .then(function(_creation) {
              if (_creation) {
                if (!_creation.qiniu_video) {
                  _creation.qiniu_thumb = _audio.qiniu_thumb
                  _creation.save()
                }
              }
            })
            console.log(_audio)
            console.log('同步封面成功')
          })
        }
      })
  })
}


0
2
JerseyJerry
video那边加await可以。但是这边asyncMedia里面直接加await不管用。因为这个方法被调用的时候,进入到里面调用robot的方法是(也是异步)就又跳出来指向了。我是直接外面套了个promise。
2018-03-20
共2条回复

JerseyJerry

提问者

2018-03-11

 代码就是您之前上课的源代码。我贴在这里您在看下。如何调整。

function asyncMedia(videoId, audioId){

  if(!videoId) return

  

  var query = {

    _id: audioId

  }

  if(!audioId) {  

    query = {

      video: videoId

    }

  }

  Promise.all([

    Video.findOne({

      _id: videoId

    }),

    Audio.findOne(query)

  ])

  .then((data)=>{

    var video = data[0] 

    var audio = data[1]

    console.log('check data')

      if(!video || !video.public_id || !audio || !audio.public_id){

        return

      }

      var video_public_id = video.public_id

      var audio_public_id = audio.public_id.replace(/\//g, ':')

      var videoName = video_public_id.replace(/\//g, '_') + '.mp4'

      var videoURL = 'http://res.cloudinary.com/bobolin/video/upload/e_volume:-100/e_volume:400,l_video:' + audio_public_id + '/' +

      video_public_id + '.mp4'      

      var thumbName = video_public_id.replace(/\//g, '_') + '.jpg'

      var thumbURL = 'http://res.cloudinary.com/bobolin/video/upload/' + video_public_id + '.jpg'

      robot

          .saveToQiniu(videoURL, videoName)

          .catch(function(err){

            console.log(err)

          })

          .then(function(response){

            if(response && response.key) {

              audio.qiniu_video = response.key    

              audio.save().then(function(_audio){

                  Creation.findOne({

                  video: video._id,

                  audio: audio._id

                })

                .then(function(_creation){ 

                  if(_creation){

                    if(!_creation.qiniu_video){

                      _creation.qiniu_video = _audio.qiniu_video  

                      _creation.save()

                    }

                  }

                })

              })

              console.log('async video complete')

            }

          })

    robot

          .saveToQiniu(thumbURL, thumbName)

          .catch(function(err){

            console.log(err)

          })

          .then(function(response){

            if(response && response.key) {

              audio.qiniu_thumb = response.key

              audio.save().then(function(_audio){

                Creation.findOne({

                  video: video._id,

                  audio: audio._id

                })

                .then(function(_creation){

                  if(_creation){

                    if(!_creation.qiniu_video){

                      _creation.qiniu_thumb = _audio.qiniu_thumb

                      _creation.save()

                    }

                  }

                })

              })

              console.log('async thumb complete')

            }

          })

  })

}


0
0

Scott

2018-03-11

asyncMedia 是 Promise 么,如果是,看下里面的异步处理,是不是异步处理完成后,才 resolve 的, 可以用 await 来保持异步的顺序


0
1
JerseyJerry
回复有字数限制,麻烦您看下,上面贴出来的代码。是您上课的源代码。 asyncMedia 本身不是promise,但是里面包含了几个promise。 还有,因为是合成操作,不需要返回结果。不知道在哪加resolve。谢谢
2018-03-11
共1条回复

贯穿全栈React Native开发App

全面掌握React Native技术,不止步前端开发,让你移动领域大放光彩

946 学习 · 385 问题

查看课程