Discord Player
Migrate from v7

Migrate extractors

Keep a BaseExtractor through the adapter, then port it to a source plugin.

You are reading the v8 docsDev

Migrate in two phases. First keep a compatible extractor working through the adapter. Then rewrite it as a plugin.

Phase 1: keep the extractor

import { BaseExtractor, Track } from 'discord-player';
import type { ExtractorSearchContext } from 'discord-player';

class MyLegacyExtractor extends BaseExtractor {
  static identifier = 'my.source';

  async validate(query: string) {
    return query.startsWith('https://');
  }

  async handle(query: string, context: ExtractorSearchContext) {
    return this.createResponse(null, [
      new Track(this.context.player, {
        title: 'Audio',
        url: query,
        requestedBy: context.requestedBy,
        engine: query,
      }),
    ]);
  }

  async stream(track: Track) {
    return track.raw.engine as string;
  }
}

await player.extractors.register(MyLegacyExtractor, {});

register() takes the extractor class. See v7 extractors for the method mapping and limits.

Phase 2: write a plugin

import { definePlugin, Track } from 'discord-player';

export const mySource = definePlugin({
  id: 'my.source',

  setup(ctx) {
    ctx.on('search.query.match', ({ query }) => (query.startsWith('https://') ? { score: 100 } : null));

    ctx.on('search.query.resolve', ({ query }) => ({
      playlist: null,
      tracks: [new Track({ title: 'Audio', url: query })],
    }));

    ctx.on('track.stream', ({ track }) => ({ url: track.url }));
  },
});

Register plugins: [mySource()] in the Player options, or call await player.plugins.register(mySource()) later. Remove the legacy extractor first. A modern plugin and a legacy extractor must not use the same ID at the same time.

Method mapping

v7 extractorv8 operation
validatesearch.query.match
handlesearch.query.resolve
streamtrack.stream
getRelatedTrackstrack.related
bridgetrack.bridge
handlePostStreamLocal stream.transform
activate and deactivatesetup and destroy

What does not carry over

An extractor that needs raw voice packets, the old stream dispatcher, PCM or Opus format overrides, or a private session cannot run through the adapter. Move that part to Remedia features or redesign the source.

Saved tracks must not depend on raw.engine. Restored tracks need a public url or a portable sourceReference.

A remote node can only play URLs and files it can reach. A Readable from an extractor works with embedded nodes only.

Continue reading

Migrate saved data

On this page