将ffmpeg输出直接流式传输到调度程序

时间:2019-06-24 15:20:26

标签: javascript node.js ffmpeg discord.js fluent-ffmpeg

我正在尝试使用Discord机器人播放音乐,并且我想使用ffmpeg来指定音乐的开始,这很好用,但是我只能使用ffmpeg下载音乐然后再播放。我希望ffmpeg对其进行处理,然后还对其进行流处理以播放音乐。

这是我用来下载然后播放音乐的代码:

message.member.voiceChannel.join().then((con, err) => {
    ytPlay.search_video(op, (id) => {
        let stream = ytdl("https://www.youtube.com/watch?v=" + id, {
            filter: "audioonly"
        });
        let audio = fs.createWriteStream('opStream.divx');

        proc = new ffmpeg({
            source: stream
        })
        proc.withAudioCodec('libmp3lame')
            .toFormat('mp3')
            .seekInput(35)
            .output(audio)
            .run();
        proc.on('end', function() {
            let input = fs.createReadStream('opStream.divx');
            console.log('finished');
            guild.queue.push(id);
            guild.isPlaying = true;
            guild.dispatcher = con.playStream(input);
        });
    });
})

是否可以做我想做的事情?如果可以,怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用discord.js的************* Module tmp tmp.py:5:0: W0001: Function fn_stmt is deprecated since version (not specified); reason: (not specified). (deprecated) tmp.py:9:0: W0001: Function fn_version is deprecated since version 0.1.0; reason: (not specified). (deprecated) tmp.py:13:0: W0001: Function fn_reason is deprecated since version (not specified); reason: I'm mean. (deprecated) tmp.py:17:0: W0001: Function fn_both is deprecated since version 0.1.0; reason: I'm mean. (deprecated) tmp.py:20:0: W0001: Class ClassStmt is deprecated since version (not specified); reason: (not specified). (deprecated) tmp.py:24:0: W0001: Class ClassVersion is deprecated since version 0.1.0; reason: (not specified). (deprecated) tmp.py:28:0: W0001: Class ClassReason is deprecated since version (not specified); reason: I'm mean. (deprecated) tmp.py:32:0: W0001: Class ClassBoth is deprecated since version 0.1.0; reason: I'm mean. (deprecated) ------------------------------------------------------------------- Your code has been rated at 5.29/10 (previous run: -2.35/10, +7.65) StreamOptions,而不是使用ffmpeg指定音乐的起点,例如:

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.10.Final</version> </dependency> @Configuration public class SpringConfiguration { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } } @RestController @CrossOrigin @Validated public class WebController { private final Logger logger = LoggerFactory.getLogger(WebController.class); @Autowired private WebService webService; @TeamIdConstraint private Integer homeId; @TeamIdConstraint private Integer awayId; @GetMapping("/matchresultbyids") public MatchStats matchResult(@RequestParam Integer homeId, @RequestParam Integer awayId) throws MissingTeamException, InvalidTeamIdExcpetion { this.homeId = homeId; this.awayId = awayId; return webService.matchResult(this.homeId, this.awayId); } } @Documented @Constraint(validatedBy = TeamIdValidator.class) @Target({ ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface TeamIdConstraint { String message() default "Invalid team id!"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class TeamIdValidator implements ConstraintValidator<TeamIdConstraint, Integer> { @Autowired TeamResource teamResource; @Override public void initialize(TeamIdConstraint teamId) { } @Override public boolean isValid(Integer teamId, ConstraintValidatorContext cxt) { int numOfAvailableTeams = teamResource.retrieveAllTeams().size(); return teamId < 0 || teamId >= numOfAvailableTeams; } }

这对我来说很好

答案 1 :(得分:0)

是可能的,我在我的机器人中做到了。 首先,您需要安装ytdl-core

然后创建一个play.js文件,其中将包含流功能。 这段代码将:在不下载歌曲的情况下获取youtube url并流式传输它,将歌曲添加到队列中,并在歌曲播放完毕后让机器人离开

根据需要编辑代码。

exports.run = async (client, message, args, ops) => {
    if (!message.member.voiceChannel) return message.channel.send('You are not connected to a voice channel!');


    if (!args[0]) return message.channel.send('Insert a URL!');
    let validate = await ytdl.validateURL(args[0]);

    let info = await  ytdl.getInfo(args[0]);

   let data = ops.active.get(message.guild.id) || {};
    if (!data.connection) data.connection = await message.member.voiceChannel.join();
    if(!data.queue) data.queue = [];
    data.guildID = message.guild.id;

    data.queue.push({
        songTitle: info.title,
        requester: message.author.tag,
        url: args[0],
        announceChannel: message.channel.id

    });

    if (!data.dispatcher) play(client, ops, data);
    else {
        message.channel.send(`Added to queue: ${info.title} | requested by: ${message.author.tag}`)
    }
    ops.active.set(message.guild.id, data);


}
async function play(client, ops, data) {
    client.channels.get(data.queue[0].announceChannel).send(`Now Playing: ${data.queue[0].songTitle} | Requested by: ${data.queue[0].requester}`);
    client.user.setActivity(`${data.queue[0].songTitle}`, {type: "LISTENING"});

    data.dispatcher = await data.connection.playStream(ytdl(data.queue[0].url, {filter: 'audioonly'}));
    data.dispatcher.guildID = data.guildID;

    data.dispatcher.once('end', function() {
        end(client, ops, this);

    });

}
function end(client, ops, dispatcher){

    let fetched = ops.active.get(dispatcher.guildID);

    fetched.queue.shift();

    if (fetched.queue.length > 0) {
        ops.active.set(dispatcher.guildID, fetched);
        play(client, ops, fetched);
    } else {
        ops.active.delete(dispatcher.guildID);

        let vc = client.guilds.get(dispatcher.guildID).me.voiceChannel;

        if (vc) vc.leave();


    }
  }
  module.exports.help = {
    name:"play"
  }```