discordjs / voice

Implementation of the Discord Voice API for discord.js and other JS/TS libraries
Apache License 2.0
327 stars 110 forks source link

Playback ends unexpectedly in the middle of the audio. #117

Closed tignear closed 3 years ago

tignear commented 3 years ago

When playing the audio from dropbox, the playback ends unexpectedly in the middle of the audio without throwing an error. However, when playing the downloaded audio file, it will play to the end without any issue.

ends unexpectedly

  const connection = joinVoiceChannel({
    guildId: guild.id,
    channelId: vc.id,
    adapterCreator: guild.voiceAdapterCreator,
    selfMute: false,
    debug: true,
  });
  connection.on("debug",console.log);
  connection.on("error",console.error);
  const resource = createAudioResource("https://www.dropbox.com/s/5f1l6seztxvq373/Cartoon%20-%20On%20_%20On%20%28feat.%20Daniel%20Levi%29%20_NCS%20Release_.mp3?dl=1", {
    inputType: StreamType.Arbitrary,
  });
  const player = createAudioPlayer({
    behaviors: {
      noSubscriber: NoSubscriberBehavior.Pause,
    },
  });
  player.on("debug",console.log);
  player.on("error",console.error);
  player.play(resource);
  const promises = [];
  promises.push(entersState(connection, VoiceConnectionStatus.Ready, 1000 * 10));
  promises.push(entersState(player, AudioPlayerStatus.AutoPaused, 1000 * 10));
  await Promise.all(promises);
  connection.subscribe(player);
  await entersState(player, AudioPlayerStatus.Playing, 100);
  await entersState(player, AudioPlayerStatus.Idle, 2**31-1);
  connection.destroy();

play to the end

  const resource = createAudioResource(fs.createReadStream("./audio.mp3"), {
    inputType: StreamType.Arbitrary,
  });

Windows 10

--------------------------------------------------
Core Dependencies
- @discordjs/voice: 0.3.1
- prism-media: 1.2.9

Opus Libraries
- @discordjs/opus: 0.5.3
- opusscript: not found

Encryption Libraries
- sodium: not found
- libsodium-wrappers: not found
- tweetnacl: 1.0.3

FFmpeg
- version: 4.3.1-2020-11-19-essentials_build-www.gyan.dev
- libopus: yes
--------------------------------------------------

Ubuntu 20.04(WSL2)

--------------------------------------------------
Core Dependencies
- @discordjs/voice: 0.3.1
- prism-media: 1.2.9

Opus Libraries
- @discordjs/opus: 0.5.3
- opusscript: not found

Encryption Libraries
- sodium: not found
- libsodium-wrappers: not found
- tweetnacl: 1.0.3

FFmpeg
- version: 4.2.4-1ubuntu0.1
- libopus: yes
--------------------------------------------------

Relevant client options:

play to the end

state change:
from {"status":"idle","resource":false,"stepTimeout":false}
to {"status":"buffering","resource":true,"stepTimeout":false}
state change:
from {"status":"buffering","resource":true,"stepTimeout":false}
to {"status":"playing","missedFrames":0,"playbackDuration":0,"resource":true,"stepTimeout":false}
state change:
from {"status":"playing","missedFrames":0,"playbackDuration":0,"resource":true,"stepTimeout":false}
to {"status":"autopaused","missedFrames":0,"playbackDuration":0,"resource":true,"silencePacketsRemaining":5,"stepTimeout":false}
[NW] [WS] >> {"op":0,"d":{"server_id":"750031320205230311","user_id":"735835853372522546","session_id":"6a2f514b36ee6e18b5693d2695231a30","token":"64e47b95c802a107"}}
[NW] state change:
from {"code":0,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":false}
to {"code":1,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":false}
[NW] [WS] << {"op":8,"d":{"v":4,"heartbeat_interval":13750.0}}
[NW] [WS] << {"op":2,"d":{"streams":[{"type":"video","ssrc":56152,"rtx_ssrc":56153,"rid":"","quality":0,"active":false}],"ssrc":56151,"port":50008,"modes":["aead_aes256_gcm_rtpsize","aead_aes256_gcm","xsalsa20_poly1305_lite_rtpsize","xsalsa20_poly1305_lite","xsalsa20_poly1305_suffix","xsalsa20_poly1305"],"ip":"103.194.167.85","experiments":["bwe_conservative_link_estimate","bwe_remote_locus_client"]}}
[NW] state change:
from {"code":1,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":false}
to {"code":2,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56151}}
[NW] [WS] >> {"op":1,"d":{"protocol":"udp","data":{"address":"124.85.238.198","port":52993,"mode":"xsalsa20_poly1305_lite"}}}
[NW] state change:
from {"code":2,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56151}}
to {"code":3,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56151}}
[NW] [WS] << {"op":4,"d":{"video_codec":"H264","secret_key":[33,61,144,252,209,45,62,11,64,2,42,73,159,84,147,237,54,111,233,159,57,197,206,113,90,61,226,185,112,190,236,253],"mode":"xsalsa20_poly1305_lite","media_session_id":"38ee242ae2f8fe471d9f063b187675bd","audio_codec":"opus"}}
[NW] state change:
from {"code":3,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56151}}
to {"code":4,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"64e47b95c802a107","sessionID":"6a2f514b36ee6e18b5693d2695231a30","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56151,"encryptionMode":"xsalsa20_poly1305_lite","secretKey":{"0":33,"1":61,"2":144,"3":252,"4":209,"5":45,"6":62,"7":11,"8":64,"9":2,"10":42,"11":73,"12":159,"13":84,"14":147,"15":237,"16":54,"17":111,"18":233,"19":159,"20":57,"21":197,"22":206,"23":113,"24":90,"25":61,"26":226,"27":185,"28":112,"29":190,"30":236,"31":253},"sequence":48630,"timestamp":2216838939,"nonce":0,"nonceBuffer":{"type":"Buffer","data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},"speaking":false,"packetsPlayed":0}}
state change:
from {"status":"autopaused","missedFrames":0,"playbackDuration":100,"resource":true,"silencePacketsRemaining":0,"stepTimeout":false}
to {"status":"playing","missedFrames":0,"playbackDuration":100,"resource":true,"silencePacketsRemaining":0,"stepTimeout":false}
[NW] [WS] >> {"op":5,"d":{"speaking":1,"delay":0,"ssrc":56151}}
[NW] [WS] >> {"op":3,"d":1623501476079}
[NW] [WS] << {"op":6,"d":1623501476079}
[NW] [WS] >> {"op":3,"d":1623501489832}
[NW] [WS] << {"op":6,"d":1623501489832}
[NW] [WS] >> {"op":3,"d":1623501503589}
[NW] [WS] << {"op":6,"d":1623501503589}
[NW] [WS] >> {"op":3,"d":1623501517342}
[NW] [WS] << {"op":6,"d":1623501517342}
[NW] [WS] >> {"op":3,"d":1623501531100}
[NW] [WS] << {"op":6,"d":1623501531100}
[NW] [WS] >> {"op":3,"d":1623501544858}
[NW] [WS] << {"op":6,"d":1623501544858}
[NW] [WS] >> {"op":3,"d":1623501558620}
[NW] [WS] << {"op":6,"d":1623501558620}
[NW] [WS] >> {"op":3,"d":1623501572377}
[NW] [WS] << {"op":6,"d":1623501572377}
[NW] [WS] >> {"op":3,"d":1623501586135}
[NW] [WS] << {"op":6,"d":1623501586135}
[NW] [WS] >> {"op":3,"d":1623501599891}
[NW] [WS] << {"op":6,"d":1623501599891}
[NW] [WS] >> {"op":3,"d":1623501613646}
[NW] [WS] << {"op":6,"d":1623501613646}
[NW] [WS] >> {"op":3,"d":1623501627399}
[NW] [WS] << {"op":6,"d":1623501627399}
[NW] [WS] >> {"op":3,"d":1623501641152}
[NW] [WS] << {"op":6,"d":1623501641152}
[NW] [WS] >> {"op":3,"d":1623501654912}
[NW] [WS] << {"op":6,"d":1623501654912}
[NW] [WS] >> {"op":3,"d":1623501668669}
[NW] [WS] << {"op":6,"d":1623501668669}
[NW] [WS] >> {"op":5,"d":{"speaking":0,"delay":0,"ssrc":56151}}
state change:
from {"status":"playing","missedFrames":0,"playbackDuration":208120,"resource":true,"silencePacketsRemaining":0,"stepTimeout":false}
to {"status":"idle","resource":false,"stepTimeout":false}

ends unexpectedly

state change:
from {"status":"idle","resource":false,"stepTimeout":false}
to {"status":"buffering","resource":true,"stepTimeout":false}
[NW] [WS] >> {"op":0,"d":{"server_id":"750031320205230311","user_id":"735835853372522546","session_id":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","token":"8033b12c62e8ac02"}}
[NW] state change:
from {"code":0,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":false}
to {"code":1,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":false}
[NW] [WS] << {"op":8,"d":{"v":4,"heartbeat_interval":13750.0}}
[NW] [WS] << {"op":2,"d":{"streams":[{"type":"video","ssrc":56325,"rtx_ssrc":56326,"rid":"","quality":0,"active":false}],"ssrc":56324,"port":50008,"modes":["aead_aes256_gcm_rtpsize","aead_aes256_gcm","xsalsa20_poly1305_lite_rtpsize","xsalsa20_poly1305_lite","xsalsa20_poly1305_suffix","xsalsa20_poly1305"],"ip":"103.194.167.85","experiments":["bwe_conservative_link_estimate","bwe_remote_locus_client"]}}
[NW] state change:
from {"code":1,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":false}
to {"code":2,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56324}}
[NW] [WS] >> {"op":1,"d":{"protocol":"udp","data":{"address":"124.85.238.198","port":50595,"mode":"xsalsa20_poly1305_lite"}}}
[NW] state change:
from {"code":2,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56324}}
to {"code":3,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56324}}
[NW] [WS] << {"op":4,"d":{"video_codec":"H264","secret_key":[79,99,160,224,227,8,92,61,7,169,69,57,136,222,196,243,197,72,173,125,243,208,3,252,35,68,147,254,167,60,28,236],"mode":"xsalsa20_poly1305_lite","media_session_id":"38ee242ae2f8fe471d9f063b187675bd","audio_codec":"opus"}}
[NW] state change:
from {"code":3,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56324}}
to {"code":4,"ws":true,"connectionOptions":{"endpoint":"japan996.discord.media:443","serverID":"750031320205230311","token":"8033b12c62e8ac02","sessionID":"232eb0ae60b9e7bdbc536d4dcfdb1d4e","userID":"735835853372522546"},"udp":true,"connectionData":{"ssrc":56324,"encryptionMode":"xsalsa20_poly1305_lite","secretKey":{"0":79,"1":99,"2":160,"3":224,"4":227,"5":8,"6":92,"7":61,"8":7,"9":169,"10":69,"11":57,"12":136,"13":222,"14":196,"15":243,"16":197,"17":72,"18":173,"19":125,"20":243,"21":208,"22":3,"23":252,"24":35,"25":68,"26":147,"27":254,"28":167,"29":60,"30":28,"31":236},"sequence":21329,"timestamp":2610706401,"nonce":0,"nonceBuffer":{"type":"Buffer","data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},"speaking":false,"packetsPlayed":0}}
state change:
from {"status":"buffering","resource":true,"stepTimeout":false}
to {"status":"playing","missedFrames":0,"playbackDuration":0,"resource":true,"stepTimeout":false}
state change:
from {"status":"playing","missedFrames":0,"playbackDuration":0,"resource":true,"stepTimeout":false}
to {"status":"autopaused","missedFrames":0,"playbackDuration":0,"resource":true,"silencePacketsRemaining":5,"stepTimeout":false}
state change:
from {"status":"autopaused","missedFrames":0,"playbackDuration":0,"resource":true,"silencePacketsRemaining":5,"stepTimeout":false}
to {"status":"playing","missedFrames":0,"playbackDuration":0,"resource":true,"silencePacketsRemaining":5,"stepTimeout":false}
[NW] [WS] >> {"op":5,"d":{"speaking":1,"delay":0,"ssrc":56324}}
[NW] [WS] >> {"op":3,"d":1623502100140}
[NW] [WS] << {"op":6,"d":1623502100140}
[NW] [WS] >> {"op":3,"d":1623502113901}
[NW] [WS] << {"op":6,"d":1623502113901}
[NW] [WS] >> {"op":3,"d":1623502127659}
[NW] [WS] << {"op":6,"d":1623502127659}
[NW] [WS] >> {"op":5,"d":{"speaking":0,"delay":0,"ssrc":56324}}
state change:
from {"status":"playing","missedFrames":0,"playbackDuration":48520,"resource":true,"silencePacketsRemaining":5,"stepTimeout":false}
to {"status":"idle","resource":false,"stepTimeout":false}
amishshah commented 3 years ago

This seems like a connection error with FFmpeg that could be solved by setting the reconnect options when spawning FFmpeg. Could you try this and let me know if it still stops playback?

const { StreamType, createAudioResource } = require('@discordjs/voice');
const { FFmpeg } = require('prism-media');

const FFMPEG_OPUS_ARGUMENTS = [
    '-analyzeduration',
    '0',
    '-loglevel',
    '0',
    '-acodec',
    'libopus',
    '-f',
    'opus',
    '-ar',
    '48000',
    '-ac',
    '2',
];

const stream = new prism.FFmpeg({
    args: ['-reconnect_streamed', '1', '-reconnect_at_eof', '1', '-reconnect_on_network_error', '1', '-reconnect_on_http_error', '1', '-reconnect_delay_max', '5', '-i', 'your url here', ...FFMPEG_OPUS_ARGUMENTS],
});

const resource = createAudioResource(stream, { inputType: StreamType.OggOpus });
tignear commented 3 years ago

It seems certain that it is a connection-related issue with FFmpeg. I did the following and it worked fine. Thank you!

xyligan-gp commented 3 years ago

Unfortunately, links from YouTube do not play :(

LingleDev commented 3 years ago

I've tried using prism-media. I even used the example from here word-for-word, and it didn't work.