Kodik internal ID support, URL decoding
This commit is contained in:
@ -13,11 +13,15 @@ public interface KodikPlayerAPI {
|
||||
}
|
||||
|
||||
default String kinopoiskURL(String id) {
|
||||
return BASE_PLAYER_URL + "kinopoiskID%3D";
|
||||
return BASE_PLAYER_URL + "kinopoiskID%3D" + id;
|
||||
}
|
||||
|
||||
default String imdbURL(String id) {
|
||||
return BASE_PLAYER_URL + "kinopoiskID%3D";
|
||||
return BASE_PLAYER_URL + "imdbID%3D" + id;
|
||||
}
|
||||
|
||||
default String kodikIDURL(String id) {
|
||||
return BASE_PLAYER_URL + "ID%3D" + id;
|
||||
}
|
||||
|
||||
@GET("get-player")
|
||||
@ -26,9 +30,9 @@ public interface KodikPlayerAPI {
|
||||
@Query("hasPlayer") Boolean hasPlayer,
|
||||
@Query("url") String url,
|
||||
@Query("token") String token,
|
||||
@Query("ID") String kodikId,
|
||||
@Query("shikimoriID") String shikimoriID,
|
||||
@Query("kinopoiskID") String kinopoiskID,
|
||||
@Query("imdbID") String imdbID
|
||||
);
|
||||
@Query("imdbID") String imdbID);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.backend.extractor.kodik.service.anyame_backend.service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* KodikURLDecoder
|
||||
*/
|
||||
@Service
|
||||
// TODO: Test shikimori id: 1535 with KodikURLDecoder, only mp4:hls:manifest is
|
||||
// included
|
||||
// TODO: Paste some random anime urls to test decoder
|
||||
public class KodikURLDecoderService {
|
||||
private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
private static final String MANIFEST_IDENTIFIER = "mp4:hls:manifest.m3u8";
|
||||
private static final int BASE64_BLOCK_SIZE = 4;
|
||||
|
||||
/**
|
||||
* Convert a character using ROT cipher with specified rotation
|
||||
*/
|
||||
private String convertChar(char ch, int rotation) {
|
||||
boolean isLower = Character.isLowerCase(ch);
|
||||
char upperChar = Character.toUpperCase(ch);
|
||||
|
||||
if (ALPHABET.indexOf(upperChar) != -1) {
|
||||
int index = (ALPHABET.indexOf(upperChar) + rotation) % ALPHABET.length();
|
||||
char result = ALPHABET.charAt(index);
|
||||
return isLower ? String.valueOf(Character.toLowerCase(result)) : String.valueOf(result);
|
||||
}
|
||||
return String.valueOf(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to decrypt the input string by testing all possible ROT cipher rotations
|
||||
*/
|
||||
private String tryToDecrypt(String input) {
|
||||
for (int rotation = 0; rotation < 26; rotation++) {
|
||||
StringBuilder rotatedString = new StringBuilder();
|
||||
for (char ch : input.toCharArray()) {
|
||||
rotatedString.append(convertChar(ch, rotation));
|
||||
}
|
||||
|
||||
// Base64 strings must be multiples of 4 characters, add padding if needed
|
||||
int missingPaddingLength = (BASE64_BLOCK_SIZE - (rotatedString.length() % BASE64_BLOCK_SIZE))
|
||||
% BASE64_BLOCK_SIZE;
|
||||
rotatedString.append("=".repeat(missingPaddingLength));
|
||||
|
||||
try {
|
||||
byte[] decodedBytes = Base64.getDecoder().decode(rotatedString.toString());
|
||||
String decodedResult = new String(decodedBytes, StandardCharsets.UTF_8);
|
||||
|
||||
if (decodedResult.contains(MANIFEST_IDENTIFIER)) {
|
||||
return decodedResult;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
throw new KodikDecryptionException("Unable to decrypt the provided URL - no valid rotation found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method to get link data from encoded video URL
|
||||
*
|
||||
* @param videoUrl The encoded video URL
|
||||
* @return The decoded video URL
|
||||
* @throws KodikDecryptionException if decryption fails
|
||||
*/
|
||||
public String getLinkData(String videoUrl) {
|
||||
if (videoUrl == null || videoUrl.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("Video URL cannot be null or empty");
|
||||
}
|
||||
|
||||
return tryToDecrypt(videoUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom exception for Kodik decryption failures
|
||||
*/
|
||||
public static class KodikDecryptionException extends RuntimeException {
|
||||
public KodikDecryptionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user