sedmelluq / lavaplayer

Audio player library for Discord
Apache License 2.0
973 stars 247 forks source link

Only first entry in m3u is played #281

Open MagicRB opened 4 years ago

MagicRB commented 4 years ago

I use lavaplayer indirectly, through MusicBot, so pardon any gaps in my knowledge and terms, anyway, when javaplayer gets handed a URL with a m3u file, it only detects/plays the first entry in said m3u file and ignores the rest. I have tried many things, like spacing everything out, adding the extended m3u header, changing the file suffix to m3u8, nothing helped.

cwchristerw commented 2 years ago

Look #678

Alphapcka-lgtm commented 2 years ago

I ran into the same Issue. I debugged it and to it seems that in the method M3uPlaylistContainerProbe#probe(AudioReference, SeekableInputStream) it can only load one track since the method loadSingleItemPlaylist(lines) is always called. This method returns the first track that it can find. I couldn't find a find a method in there to load multiple tracks.

It also seems that the same issue exists with when loading streams, since the method HlsStreamSegmentUrlProvider.findHlsEntryUrl(lines) also only returns a single string.

method M3uPlaylistContainerProbe#probe(AudioReference, SeekableInputStream):

@Override
  public MediaContainerDetectionResult probe(AudioReference reference, SeekableInputStream inputStream) throws IOException {
    if (!checkNextBytes(inputStream, M3U_HEADER_TAG) && !checkNextBytes(inputStream, M3U_ENTRY_TAG)) {
      return null;
    }

    log.debug("Track {} is an M3U playlist file.", reference.identifier);
    String[] lines = DataFormatTools.streamToLines(inputStream, StandardCharsets.UTF_8);

    String hlsStreamUrl = HlsStreamSegmentUrlProvider.findHlsEntryUrl(lines);

    if (hlsStreamUrl != null) {
      AudioTrackInfoBuilder infoBuilder = AudioTrackInfoBuilder.create(reference, inputStream);
      AudioReference httpReference = HttpAudioSourceManager.getAsHttpReference(reference);

      if (httpReference != null) {
        return supportedFormat(this, TYPE_HLS_OUTER, infoBuilder.setIdentifier(httpReference.identifier).build());
      } else {
        return refer(this, new AudioReference(hlsStreamUrl, infoBuilder.getTitle(),
            new MediaContainerDescriptor(this, TYPE_HLS_INNER)));
      }
    }

    // Loads the first track in the m3u file that it can find and returns .
    MediaContainerDetectionResult result = loadSingleItemPlaylist(lines);
    if (result != null) {
      return result;
    }

    return unsupportedFormat(this, "The playlist file contains no links.");
  }
Alphapcka-lgtm commented 2 years ago

I tested also pls and plain-playlist files. All of them also have the same problem. I would say that's a general problem with all playlist container probes.

Alphapcka-lgtm commented 2 years ago

All container probes seem to be working with the class MediaContainerDetectionResult which doesn't appear to have any support for playlists, only for single tracks.

The probes implement the interface MediaContainerProbe which doesn't allow the return of any sort of collection.