函数运行两次但只被调用一次?

时间:2021-05-31 21:45:44

标签: javascript node.js bash child-process

此代码有效。它在第一个 getClipFile 上抛出错误,因为 ffmpeg 尚未完成。我有点理解这一点,但它以某种方式再次运行?

我想让它运行一次,在我的 bash 脚本完成后。 我也无法理解如何简单地将其全部包装在一个函数中并等待它。

谢谢! JS:

const gameModel = require('../models/gameSchema')
const fs = require("fs");
const { MessageAttachment } = require('discord.js')
const { exec } = require('child_process')


module.exports = {
  name: 'contestsubmit',

  async execute(message, args, client, Discord ) {
 
    const channel = await client.channels.cache.get('830145067738071092')
    const bashScript = "/home/ubuntu/smashbot/utils/clipper.sh"
    const youtubeURL = args[0]
    const clipStart = +(args[1].split(':').reduce((acc,time) => (60 * acc) + +time))
    const clipEnd = +(args[2].split(':').reduce((acc,time) => (60 * acc) + +time))
    const clipID = message.id
    const clipType = "Play"
    let i = "";
    message.delete()

    const myShellScript = exec(`sh ${bashScript} "${youtubeURL}" ${clipType} ${clipStart} ${clipEnd} ${clipID}`)

    myShellScript.stdout.on('data', (data) => {
      i += '23'
      console.log('i==================',i)
      getClipFile()
    })

    myShellScript.stderr.on('data', (data) => {  
      console.error(data);
    })

    const getClipFile = () => {
      fs.readFile(`/home/ubuntu/smashbot/clip-${clipType}-${clipID}.mp4`, (err, data) => {
        if (err) {
          console.error(err)
          return
        }
        const stats = fs.statSync(`/home/ubuntu/smashbot/clip-${clipType}-${clipID}.mp4`);
        const fileSizeInBytes = stats.size
        console.log('FILE SIZE', fileSizeInBytes)
        const videoAttachment = new MessageAttachment(data, `${clipID}.mp4`)
        channel.send(`**Nominated for Play of the Week!**`, videoAttachment)
        console.log('sending clip?')
    })}
  }}

重击:

#!/bin/bash

if [ $# -ne 5 ]; then
        echo 'Illegal number of parameters. Needs  parameters:'
        echo 'Usage:'
        echo './clipper.sh YOUTUBE_URL FILE GAME_START GAME_END'
        echo
        echo 'Parameters:'
        echo '    - YOUTUBE_URL  No "https://", just the youtube.com'
        echo '    - CLIP_TYPE:        Clip Type: Choose "Play" or "Life"'
        echo '    - CLIP_START:  Start time of game in seconds'
        echo '    - CLIP_END:    Emd time of game in seconds'
        echo '                   (video format and quality options etc.)'
        exit 1
fi
YOUTUBE_URL="$1"
CLIP_TYPE="$2"
CLIP_START="$3"
CLIP_END="$4"
INDEX="$5"

# Filename of the source video (without extension)
BASENAME="${CLIP_TYPE%.*}"
# Extension for the video parts
EXTENSION="mp4"
# Filename of the next video part
NEXTFILENAME="clip-$BASENAME-$INDEX.$EXTENSION"

 # Encode next part
 echo ffmpeg -ss $CLIP_START -i youtube-dl -f 22 --get-url $YOUTUBE_URL -to $CLIP_END -c copy $NEXTFILENAME

 ffmpeg -i $(youtube-dl -f 22 --get-url $YOUTUBE_URL) -ss $CLIP_START -to $CLIP_END -c copy $NEXTFILENAME
 echo "Clipped $CLIP_TYPE: starts at $CLIP_START and ends at $CLIP_END"

1 个答案:

答案 0 :(得分:1)

在调用 end 之前,您需要等待 getClipFile() 事件。每次获得数据缓冲区时都会调用它。

    myShellScript.stdout.on('data', (data) => {
      i += '23'
      console.log('i==================',i)
    });
    myShellScript.stdout.on('end', () => getClipFile());