Skip to content

Commit

Permalink
Add TVHTML5 playback-only client.
Browse files Browse the repository at this point in the history
  • Loading branch information
devoxin committed Dec 2, 2024
1 parent fb542e6 commit 60b0fdc
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ Currently, the following clients are available for use:
- ✔ Opus formats.
- `IOS`
- ❌ No Opus formats (requires transcoding).
- `TV`
<!-- check oauth compatibility -->
- ✔ Opus formats.
- ❌ No mix/playlist/search/video *lookup* support.
- ❌ Playback only.
- `TVHTML5EMBEDDED`
- ✔ Opus formats.
- ❌ No playlist support.
Expand Down
91 changes: 91 additions & 0 deletions common/src/main/java/dev/lavalink/youtube/clients/Tv.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package dev.lavalink.youtube.clients;

import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity;
import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface;
import com.sedmelluq.discord.lavaplayer.track.AudioItem;
import dev.lavalink.youtube.CannotBeLoaded;
import dev.lavalink.youtube.YoutubeAudioSourceManager;
import dev.lavalink.youtube.clients.skeleton.StreamingNonMusicClient;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;

public class Tv extends StreamingNonMusicClient {
public static ClientConfig BASE_CONFIG = new ClientConfig()
.withApiKey("AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
.withClientName("TVHTML5")
.withClientField("clientVersion", "7.20240724.13.00");

protected ClientOptions options;

public Tv() {
this(ClientOptions.DEFAULT);
}

public Tv(@NotNull ClientOptions options) {
this.options = options;
}

@Override
@NotNull
protected ClientConfig getBaseClientConfig(@NotNull HttpInterface httpInterface) {
return BASE_CONFIG.copy();
}

@Override
@NotNull
public String getPlayerParams() {
return WEB_PLAYER_PARAMS;
}

@Override
@NotNull
public ClientOptions getOptions() {
return this.options;
}

@Override
public boolean canHandleRequest(@NotNull String identifier) {
return false;
}

@Override
public boolean supportsOAuth() {
return true;
}

@Override
@NotNull
public String getIdentifier() {
return BASE_CONFIG.getName();
}

@Override
public AudioItem loadPlaylist(@NotNull YoutubeAudioSourceManager source,
@NotNull HttpInterface httpInterface,
@NotNull String playlistId,
@Nullable String selectedVideoId) {
throw new FriendlyException("This client cannot load playlists", Severity.COMMON,
new RuntimeException("TVHTML5 cannot be used to load playlists"));
}

@Override
public AudioItem loadVideo(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String videoId) throws CannotBeLoaded, IOException {
throw new FriendlyException("This client cannot load videos", Severity.COMMON,
new RuntimeException("TVHTML5 cannot be used to load videos"));
}

@Override
public AudioItem loadMix(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String mixId, @Nullable String selectedVideoId) {
throw new FriendlyException("This client cannot load mixes", Severity.COMMON,
new RuntimeException("TVHTML5 cannot be used to load mixes"));
}

@Override
public AudioItem loadSearch(@NotNull YoutubeAudioSourceManager source, @NotNull HttpInterface httpInterface, @NotNull String searchQuery) {
throw new FriendlyException("This client cannot search", Severity.COMMON,
new RuntimeException("TVHTML5 cannot be used to search"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ public AudioItem loadPlaylist(@NotNull YoutubeAudioSourceManager source,
public AudioItem loadSearchMusic(@NotNull YoutubeAudioSourceManager source,
@NotNull HttpInterface httpInterface,
@NotNull String searchQuery) {
throw new UnsupportedOperationException();
throw new FriendlyException("This client cannot search music", Severity.COMMON,
new RuntimeException(getIdentifier() + " cannot be used to search music"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ public TrackFormats loadFormats(@NotNull YoutubeAudioSourceManager source,
boolean anyFailures = false;

for (JsonBrowser merged : mergedFormats.values()) {
anyFailures = anyFailures || !extractFormat(merged, formats, isLive);
if (!extractFormat(merged, formats, isLive)) {
anyFailures = true;
}
}

for (JsonBrowser adaptive : adaptiveFormats.values()) {
anyFailures = anyFailures || !extractFormat(adaptive, formats, isLive);
if (!extractFormat(adaptive, formats, isLive)) {
anyFailures = true;
}
}

if (formats.isEmpty() && anyFailures) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ private enum ClientMapping implements ClientReference {
ANDROID_VR(AndroidVr::new),
IOS(Ios::new),
MUSIC(Music::new),
TV(Tv::new),
TVHTML5EMBEDDED(TvHtml5Embedded::new),
WEB(Web::new),
WEBEMBEDDED(WebEmbedded::new),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ private enum ClientMapping implements ClientReference {
ANDROID_VR(AndroidVrWithThumbnail::new),
IOS(IosWithThumbnail::new),
MUSIC(MusicWithThumbnail::new),
TV(Tv::new), // This has no WithThumbnail companion as it's a playback-only client.
TVHTML5EMBEDDED(TvHtml5EmbeddedWithThumbnail::new),
WEB(WebWithThumbnail::new),
WEBEMBEDDED(WebEmbeddedWithThumbnail::new),
Expand Down

0 comments on commit 60b0fdc

Please sign in to comment.