زیرنویس یاب

مستندات API زیرنویس یاب

به مستندات API وب‌سرویس زیرنویس یاب خوش آمدید. با استفاده از این API می‌توانید از قابلیت‌های جستجو و دانلود زیرنویس در اپلیکیشن‌ها و سرویس‌های خود استفاده کنید.

نکات کلی

  • تمام درخواست‌ها باید با متد POST ارسال شوند.
  • آدرس اصلی API به صورت زیر است:
POST https://sub-plus.ir/api.php

۱. جستجوی زیرنویس

برای جستجوی یک فیلم یا سریال، پارامترهای زیر را ارسال کنید.

پارامترها

نام پارامتر نوع وضعیت توضیحات
q رشته اجباری نام فیلم یا سریال مورد نظر برای جستجو.
l رشته اختیاری زبان زیرنویس. (مثال: 'English', 'فارسی'). در صورت عدم ارسال، زبان پیش‌فرض فارسی خواهد بود.

نمونه پاسخ موفق (JSON)

{
  "ok": true,
  "count": 1,
  "result": [
    {
      "title": "News of the World (2020)",
      "tag": "MLalcVMVQMqbd47WDaOHt5m0E2bDaUFUTONpeZTeud1ns4/dWJH0ruvo4K1hIojIbdey+u4NYOsV8JxgwbMg3g==",
      "series": false,
      "comment": "By\nmeisam_t72\n...",
      "info": "News.of.the.World.2020.720p.BluRay.x264.AAC-[YTS.MX]...",
      "pic":"https:\/\/isubcdn.com\/public\/images\/2022\/261\/4\/96d89d1b-1a5f-4632-84fd-f0d2b407eca6.jpg",
      "imdb":"tt6878306"
    }
  ]
}

نمونه کد برای جستجو

<?php
$apiUrl = 'https://sub-plus.ir/api.php';
$postData = [
    'q' => 'game of thrones',
    'l' => 'English' // This parameter is optional
];

$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

if ($data && $data['ok'] === true && $data['count'] > 0) {
    echo "Found " . $data['count'] . " results.\n";
    $firstResult = $data['result'][0];
    echo "Title: " . $firstResult['title'] . "\n";
    echo "Tag for download: " . $firstResult['tag'] . "\n";
} else {
    echo "No results found or an error occurred.\n";
    print_r($data);
}
?>
const apiUrl = 'https://sub-plus.ir/api.php';
const formData = new FormData();
formData.append('q', 'game of thrones');
formData.append('l', 'English'); // This parameter is optional

async function searchSubtitles() {
    try {
        const response = await fetch(apiUrl, {
            method: 'POST',
            body: formData
        });
        const data = await response.json();

        if (data?.ok && data.count > 0) {
            console.log(`Found ${data.count} results.`);
            const firstResult = data.result[0];
            console.log(`Title: ${firstResult.title}`);
            console.log(`Tag for download: ${firstResult.tag}`);
            // let downloadTag = firstResult.tag;
        } else {
            console.log("No results found or an error occurred.", data);
        }
    } catch (error) {
        console.error("Request failed:", error);
    }
}

searchSubtitles();
import requests

api_url = 'https://sub-plus.ir/api.php'
payload = {
    'q': 'game of thrones',
    'l': 'English'  # This parameter is optional
}

try:
    response = requests.post(api_url, data=payload)
    response.raise_for_status()
    data = response.json()

    if data.get('ok') and data.get('count') > 0:
        print(f"Found {data['count']} results.")
        first_result = data['result'][0]
        print(f"Title: {first_result['title']}")
        print(f"Tag for download: {first_result['tag']}")
        # download_tag = first_result['tag']
    else:
        print("No results found or an error occurred.", data)

except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")
// Requires OkHttp library: implementation("com.squareup.okhttp3:okhttp:4.9.3")
import okhttp3.*;
import java.io.IOException;

public class SubtitleApi {
    private static final OkHttpClient client = new OkHttpClient();
    private static final String API_URL = "https://sub-plus.ir/api.php";

    public static void searchSubtitles(String query, String language) {
        FormBody.Builder formBuilder = new FormBody.Builder().add("q", query);
        if (language != null) {
            formBuilder.add("l", language);
        }
        RequestBody formBody = formBuilder.build();

        Request request = new Request.Builder().url(API_URL).post(formBody).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace(); // Handle error on UI thread
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                
                final String responseData = response.body().string();
                System.out.println(responseData);
                // Parse JSON with Gson/Moshi and update UI thread
            }
        });
    }
}

لیست زبان ها

"English" => "english"

"فارسی" => "farsi_persian"

"العربية" => "arabic"

"Español" => "spanish"

"Português" => "portuguese"

"Italiano" => "italian"

"Nederlands" => "dutch"

"עברית" => "hebrew"

"Bahasa Indonesia" => "indonesian"

"Dansk" => "danish"

"Norsk" => "norwegian"

"বাংলা" => "bengali"

"Български" => "bulgarian"

"Hrvatski" => "croatian"

"Svenska" => "swedish"

"Tiếng Việt" => "vietnamese"

"Čeština" => "czech"

"Suomi" => "finnish"

"Français" => "french"

"Deutsch" => "german"

"Ελληνικά" => "greek"

"Magyar" => "hungarian"

"Íslenska" => "icelandic"

"日本語" => "japanese"

"Македонски" => "macedonian"

"Bahasa Melayu" => "malay"

"Polski" => "polish"

"Română" => "romanian"

"Русский" => "russian"

"Српски" => "serbian"

"ไทย" => "thai"

"Türkçe" => "turkish"

۲. دریافت لینک دانلود

پس از دریافت `tag` از مرحله جستجو، آن را با کلید `dl` ارسال کنید تا لینک مستقیم دانلود را دریافت نمایید.

پارامترها

نام پارامتر نوع وضعیت توضیحات
dl رشته اجباری مقدار `tag` که از نتیجه جستجو به دست آمده است.

نمونه پاسخ موفق (JSON)

{
  "ok": true,
  "download": "http://sub-plus.ir/download/news-of-the-world-2466179.zip"
}

نمونه کد برای دانلود و ذخیره فایل

<?php
$downloadTag = '...'; // Tag from search result
$apiUrl = 'https://sub-plus.ir/api.php';
$postData = ['dl' => $downloadTag];

$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => http_build_query($postData),
    CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

if ($data?.ok && isset($data['download'])) {
    $downloadUrl = $data['download'];
    $fileName = basename($downloadUrl);
    
    if (file_put_contents($fileName, file_get_contents($downloadUrl))) {
        echo "File saved as {$fileName}\n";
    } else {
        echo "Failed to save file.\n";
    }
} else {
    echo "Failed to get download link.\n";
}
?>
// Node.js environment example
const fetch = require('node-fetch');
const fs = require('fs');
const path = require('path');

const apiUrl = 'https://sub-plus.ir/api.php';
const downloadTag = '...'; // Tag from search result

async function getAndDownloadSubtitle() {
    try {
        const formData = new FormData();
        formData.append('dl', downloadTag);
        const linkResponse = await fetch(apiUrl, { method: 'POST', body: formData });
        const linkData = await linkResponse.json();

        if (linkData?.ok && linkData.download) {
            const downloadUrl = linkData.download;
            console.log(`Download URL: ${downloadUrl}`);

            const fileResponse = await fetch(downloadUrl);
            const buffer = await fileResponse.buffer();
            const fileName = path.basename(new URL(downloadUrl).pathname);
            
            fs.writeFileSync(fileName, buffer);
            console.log(`File saved as ${fileName}`);
        } else {
            console.log("Failed to get download link.", linkData);
        }
    } catch (error) {
        console.error("An error occurred:", error);
    }
}

getAndDownloadSubtitle();
import requests
import os

api_url = 'https://sub-plus.ir/api.php'
download_tag = '...' # Tag from search result
payload = {'dl': download_tag}

try:
    link_response = requests.post(api_url, data=payload)
    link_response.raise_for_status()
    link_data = link_response.json()

    if link_data.get('ok') and link_data.get('download'):
        download_url = link_data['download']
        print(f"Download URL: {download_url}")

        file_name = os.path.basename(download_url)
        with requests.get(download_url, stream=True) as r:
            r.raise_for_status()
            with open(file_name, 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        print(f"File saved as {file_name}")
    else:
        print("Failed to get download link.", link_data)

except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")
// Requires OkHttp library
import okhttp3.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.File;

public class SubtitleDownloader {
    private static final OkHttpClient client = new OkHttpClient();
    private static final String API_URL = "https://sub-plus.ir/api.php";

    public static void getAndSaveSubtitle(String tag, File destinationFolder) {
        RequestBody formBody = new FormBody.Builder().add("dl", tag).build();
        Request request = new Request.Builder().url(API_URL).post(formBody).build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Failed to get download link: " + response);

            // Assuming the response is JSON, parse it to get the URL
            // This requires a JSON library like Gson or Jackson
            // For simplicity, we'll manually parse it here.
            String responseData = response.body().string();
            String downloadUrl = parseDownloadUrl(responseData); // Implement this function

            if (downloadUrl != null) {
                System.out.println("Download URL: " + downloadUrl);
                downloadFile(downloadUrl, destinationFolder);
            } else {
                System.out.println("Could not find download URL in response.");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void downloadFile(String url, File destinationFolder) throws IOException {
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Failed to download file: " + response);

            String fileName = new File(url).getName();
            File destinationFile = new File(destinationFolder, fileName);

            try (InputStream in = response.body().byteStream();
                 FileOutputStream out = new FileOutputStream(destinationFile)) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
                System.out.println("File saved to: " + destinationFile.getAbsolutePath());
            }
        }
    }
    
    // A simple parser, for production use a library like Gson.
    private static String parseDownloadUrl(String json) {
        // Example: {"ok":true,"download":"http://..."}
        String key = "\"download\":\"";
        int start = json.indexOf(key);
        if (start == -1) return null;
        start += key.length();
        int end = json.indexOf("\"", start);
        if (end == -1) return null;
        return json.substring(start, end);
    }
}

۳. خطاهای رایج

در صورت بروز خطا، پاسخ دریافتی شامل `{"ok": false}` و یک `description` خواهد بود.

ارسال با متد اشتباه (مثلاً GET)

{
  "ok": false,
  "description": "Bad Request: Only POST method is supported"
}

ارسال پارامترهای اشتباه یا ناقص

{
  "ok": false,
  "description": "Bad Request: Parameter not found"
}