# Slicedrive Video Extractor Implementation Guide

## Overview

Slicedrive extractor memungkinkan sistem kami untuk mengekstrak dan memutar video dari provider Slicedrive langsung di player kami tanpa perlu meninggalkan situs.

## Bagaimana Slicedrive Bekerja

### Struktur URL Slicedrive

Slicedrive menggunakan format URL dengan hash fragment untuk mengidentifikasi video:

```
https://cdn2.slicedrive.my.id/#/J194Mu.mp4
                                ↑
                          Video identifier
```

### Flow Ekstraksi

1. **Fetch HTML**: Ambil halaman embed Slicedrive
2. **Parse JSON Configuration**: Ekstrak lokasi file `videos.json` dari kode JavaScript
3. **Fetch JSON**: Ambil daftar video dari `videos.json`
4. **Match Video**: Cari video berdasarkan nama dari URL fragment
5. **Extract CDN URL**: Ambil CDN URL dari entry video yang cocok
6. **Validate**: Pastikan URL valid sebelum mengembalikan

### Contoh Respons JSON Slicedrive

```json
{
  "videos": [
    {
      "name": "J194Mu.mp4",
      "cdn": "https://cdn2.slicedrive.com/VGAN9Mgy1.mp4"
    },
    {
      "name": "video2.mp4",
      "cdn": "https://cdn2.slicedrive.com/other-url.mp4"
    }
  ]
}
```

## File: SlicedriveExtractor.php

**Lokasi**: `app/Services/Extractors/SlicedriveExtractor.php`

### Method Utama

#### `extract(string $embedUrl): ?string`

Method utama yang melakukan ekstraksi CDN URL dari embed URL Slicedrive.

```php
$service = app(\App\Services\VideoService::class);
$extractor = $service->getExtractorFor('slicedrive');
$cdnUrl = $extractor->extract('https://cdn2.slicedrive.my.id/#/J194Mu.mp4');
// Returns: https://cdn2.slicedrive.com/VGAN9Mgy1.mp4
```

### Method Pendukung

#### `extractVideoName(string $url): ?string`

Mengekstrak nama video dari URL fragment.

```php
// Input:  https://domain.com/#/J194Mu.mp4
// Output: J194Mu.mp4
```

#### `extractFromJson(string $html, string $embedUrl, ?string $videoName): ?string`

Mengekstrak CDN URL dari konfigurasi JSON:
1. Cari lokasi `videos.json` di HTML
2. Fetch file JSON dari lokasi tersebut
3. Parse JSON dan cari video berdasarkan nama
4. Return CDN URL jika ditemukan

#### `getBaseUrl(string $url): string`

Mengekstrak base URL dari embed URL untuk resolusi URL relatif.

```php
// Input:  https://cdn2.slicedrive.my.id/#/J194Mu.mp4
// Output: https://cdn2.slicedrive.my.id
```

#### `resolveUrl(string $url, string $baseUrl): string`

Mengonversi URL relatif menjadi URL absolut.

```php
// Input:  "videos.json", "https://cdn2.slicedrive.my.id"
// Output: https://cdn2.slicedrive.my.id/videos.json
```

## Integration dengan VideoService

Extractor sudah terdaftar di [app/Services/VideoService.php](app/Services/VideoService.php) dengan mapping:

```php
private array $extractors = [
    'slicedrive'      => SlicedriveExtractor::class,
    'slicedrive.com'  => SlicedriveExtractor::class,
    'slicadrive.com'  => SlicedriveExtractor::class,
    // ...
];
```

## Cara Menggunakan

### 1. Manual Test di Tinker

```bash
php artisan tinker
```

```php
$extractor = app(\App\Services\VideoService::class)->getExtractorFor('slicedrive');
$url = 'https://cdn2.slicedrive.my.id/#/J194Mu.mp4';
$result = $extractor->extract($url);
echo $result; // Output: https://cdn2.slicedrive.com/VGAN9Mgy1.mp4
```

### 2. Automatic Extraction untuk Video di Database

Sistem akan secara otomatis mengekstrak video menggunakan extractor yang sesuai dengan provider.

```php
// In VideoService::resolvePlayMode()
$extractor = $this->getExtractor($video->provider);
$extracted = $extractor->extract($video->embed_url);
```

### 3. Update Video dengan URL Terekstak

```php
$video = \App\Models\Video::where('slug', 'Od2AXq3p')->first();
$extractor = app(\App\Services\VideoService::class)->getExtractorFor('slicedrive');
$cdnUrl = $extractor->extract($video->embed_url);

if ($cdnUrl) {
    $video->hls_url = $cdnUrl;
    $video->play_mode = 'DIRECT';
    $video->status = 'ready';
    $video->last_extracted_at = now();
    $video->extract_failed = false;
    $video->save();
}
```

## Error Handling

Extractor menggunakan logging untuk debugging:

```bash
# Check logs
tail -f storage/logs/laravel.log | grep -i slicedrive
```

### Possible Errors

1. **JSON URL Not Found**: Struktur HTML berbeda dari yang diharapkan
   - Log: `"Slicedrive: JSON_URL not found"`
   - Solusi: Update regex pattern di `extractFromJson()`

2. **JSON Fetch Failed**: Server menolak request atau file tidak ada
   - Log: `"Slicedrive: Failed to fetch JSON"`
   - Solusi: Check server availability, headers, atau authentication

3. **Invalid JSON Structure**: Format JSON berbeda dari yang diharapkan
   - Log: `"Slicedrive: Invalid JSON structure"`
   - Solusi: Update parsing logic

4. **Video Name Not Found**: Video tidak ada di JSON dengan nama yang dicari
   - Log: `"Slicedrive: Video name not found in JSON"`
   - Solusi: Fallback otomatis ke video pertama

## Fallback Mechanisms

Extractor memiliki beberapa mekanisme fallback:

1. **JSON Configuration**: Try extract dari JSON terlebih dahulu
2. **Packed JavaScript**: Jika JSON gagal, coba unpack packed JavaScript
3. **Direct URL Regex**: Cari URL langsung di HTML
4. **Generic Search**: Gunakan generic extractor sebagai fallback terakhir

## Monitoring

### Check Extraction Status

```bash
php artisan tinker << 'EOF'
$videos = \App\Models\Video::where('provider', 'slicedrive')->get();
$videos->each(fn($v) => echo "{$v->slug} | Status: {$v->status} | Extracted: " . ($v->last_extracted_at ?: 'NEVER') . "\n");
EOF
```

### Re-extract Videos

```bash
php artisan tiniker << 'EOF'
$videos = \App\Models\Video::where('provider', 'slicedrive')->where('extract_failed', true)->get();
$extractor = app(\App\Services\VideoService::class)->getExtractorFor('slicedrive');
$videos->each(function($v) use ($extractor) {
    $result = $extractor->extract($v->embed_url);
    if ($result) {
        $v->update([
            'hls_url' => $result,
            'play_mode' => 'DIRECT',
            'status' => 'ready',
            'extract_failed' => false,
            'last_extracted_at' => now(),
        ]);
        echo "✅ {$v->slug}\n";
    } else {
        echo "❌ {$v->slug}\n";
    }
});
EOF
```

## Maintenance

### Update Extractor

Jika Slicedrive mengubah struktur halaman:

1. Check HTML structure dengan curl:
   ```bash
   curl -s 'https://cdn2.slicedrive.my.id/#/VideoID.mp4' | head -100
   ```

2. Update regex patterns di extractor
3. Test dengan video baru
4. Deploy changes

### Debug Specific Video

```bash
php artisan tinker << 'EOF'
$url = 'https://cdn2.slicedrive.my.id/#/J194Mu.mp4';

// Fetch HTML
$html = file_get_contents($url);
echo "HTML Length: " . strlen($html) . "\n";

// Test JSON_URL extraction
if (preg_match('/const\s+JSON_URL\s*=\s*["\']([^"\']+)["\']/', $html, $m)) {
    echo "Found JSON URL: {$m[1]}\n";
} else {
    echo "JSON URL not found\n";
}
EOF
```

## Performance

- **Extraction Time**: ~1-2 detik per video (tergantung server response)
- **Caching**: Video URL di-cache di database setelah extraction
- **Re-extraction**: Hanya dilakukan jika diperlukan

## Kesimpulan

SlicedriveExtractor sudah fully implemented dan terintegrasi dengan sistem. Video dari provider Slicedrive sekarang dapat diputar langsung melalui player kami tanpa pengguna harus meninggalkan situs.
