Dokumen ini mendemonstrasikan praktik terbaik bagi Agent dalam mengakses layanan ApsaraVideo VOD Alibaba Cloud melalui indeks <a class="text-blue-link hover:text-black dark:text-blue-link-dark dark:hover:text-white" href="https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/vod/llms/llms.txt" id="cbd45583b0yim">llms.txt</a>, menggunakan dua demo end-to-end.
Pastikan Anda telah membaca panduan memulai untuk Agen dan memahami struktur dasar file <a class="text-blue-link hover:text-black dark:text-blue-link-dark dark:hover:text-white" data-init-id="cbd45583b0yim" href="https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/vod/llms/llms.txt" id="78443e4819ujp">llms.txt</a>.
Jika Anda belum menginstal Coding Agent, lihat apendiks: Pemilihan dan pemeriksaan mandiri Coding Agent.
Alur kerja agent untuk menggunakan llms.txt
Bagian ini menjelaskan alur kerja dan pembagian tugas antara developer dan Agent, yang menjadi fondasi bagi dua demo berikutnya. Tabel Keputusan Desain Utama pada setiap demo menunjukkan penerapan metodologi ini dalam skenario tertentu.
Pembagian peran: developer vs. Agent
Tabel berikut merinci pembagian tanggung jawab. Developer menyampaikan kebutuhan, menyiapkan lingkungan, dan menerima hasil, sedangkan Agent menangani pengambilan dokumen, desain solusi, dan pembuatan kode.
Fase | Developer | Agent |
Inisiasi kebutuhan | Menjelaskan kebutuhan dalam bahasa alami. | - |
Pengambilan dokumen | - | Membaca indeks |
Pemahaman dokumen | - | Mengambil dokumentasi terperinci untuk mengekstraksi parameter request/respons, contoh kode, dan catatan penting. |
Desain solusi | Memastikan atau menyesuaikan solusi. | Mengusulkan solusi implementasi berdasarkan dokumentasi dan menjelaskan pilihan teknologinya. |
Pembuatan kode | - | Menghasilkan kode yang dapat dijalankan termasuk penanganan error. |
Konfigurasi lingkungan | Mengonfigurasi AccessKey, menginstal dependensi, dan menyiapkan konsol. | Memberikan perintah dan panduan konfigurasi. |
Eksekusi dan verifikasi | Menjalankan kode dan memastikan hasilnya. | Menjelaskan output dan melakukan troubleshooting masalah. |
Alur kerja internal Agent
Agent memproses kebutuhan secara internal dalam empat fase berurutan, dengan output setiap fase menjadi input bagi fase berikutnya.
Fase 1: Membaca indeks llms.txt
Seluruh file indeks (~250 baris) dimuat dalam satu operasi untuk melakukan tiga tugas berikut:
Mengurai bagian
Quick startguna memetakan skenario ke path dokumen.Mengekstraksi bagian
Common mistakes to avoidsebagai batasan ketat dalam pembuatan kode selanjutnya.Menentukan topologi dokumen, termasuk modul utama dan submodulnya.
Fase 2: Mencocokkan skenario dan menemukan dokumentasi
Mencocokkan kata kunci kebutuhan dengan judul skenario di bagian
Quick start.Jika ditemukan skenario yang cocok, gunakan path dokumen yang sesuai secara langsung.
Jika tidak ada skenario yang cocok, pindai indeks modul untuk mengidentifikasi satu hingga tiga sub-dokumen yang paling relevan.
Buat URL: BASE_URL + url_encode(relative_path).
Fase 3: Mengambil dokumen dan mengekstraksi informasi
Elemen-elemen berikut diekstraksi dari sub-dokumen sebagai input untuk pembuatan kode: nama API, parameter request/respons, contoh kode, batas QPS, kode kesalahan, batasan wilayah, serta catatan tambahan.
Fase 4: Pembuatan kode
Sebelum membuat kode, Agent melakukan pemeriksaan mandiri terhadap daftar periksa Common mistakes to avoid:
Jika menggunakan AccessKey akun utama, gantilah dengan RAM user.
Jika menerapkan polling status, beralihlah ke notifikasi event.
Jika URL tidak di-encode, panggil
url_encode.Jika membuat kredensial baru untuk setiap request, gunakan kembali dan refresh objek
Credentialtersebut.
Agent juga menambahkan logika backoff QPS dan pemrosesan asinkron ke kode akhir.
Aturan pembuatan URL
File indeks menggunakan path relatif untuk mereferensikan sub-dokumen. Agent harus mengonversinya menjadi URL absolut saat mengambilnya.
Base URL: https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/vod/llms/
Document URL = Base URL + URL encoding(relative path, dengan "./" awal dihapus)
Contoh:
Di llms.txt: [server-side upload](./媒体上传/服务端上传.md)
Full URL: Base URL + %E5%AA%92%E4%BD%93%E4%B8%8A%E4%BC%A0/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%B8%8A%E4%BC%A0.mdDemo end-to-end
Modul ini menyediakan dua demo end-to-end untuk sisi server dan sisi klien. PlayURL yang dikembalikan oleh operasi GetPlayInfo menghubungkan kedua sisi untuk membentuk alur kerja lengkap yang tertutup.
Prasyarat
Langkah | Lokasi | Aksi |
1 | Alibaba Cloud Console | Aktifkan layanan ApsaraVideo VOD |
2 | RAM Console | Buat RAM user, berikan kebijakan |
3 | ApsaraVideo VOD Console | Konfigurasi kelompok template transkoding (catat TemplateGroupId) |
4 | ApsaraVideo VOD Console | Konfigurasi URL callback HTTP (Configuration Management > Callback Settings) |
5 | Terminal lokal |
|
6 | Terminal lokal | Setel variabel lingkungan |
Demo sisi server: Upload batch, transkoding, dan mendapatkan URL pemutaran
Demo ini menunjukkan bagaimana Agent menggunakan indeks llms.txt untuk membangun alur kerja lengkap di sisi server, mencakup upload batch URL, transkoding otomatis dengan menentukan kelompok template transkoding saat upload dan melacak progres melalui notifikasi event, serta mendapatkan URL pemutaran setelah transkoding selesai.
Prompt yang dikirimkan ke agent
Silakan gunakan dokumen llms.txt (https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/vod/llms/llms.txt) untuk mengimplementasikan alur kerja demo lengkap dalam Python untuk ApsaraVideo VOD, termasuk upload batch, transkoding otomatis, dan mendapatkan URL pemutaran.
Persyaratan spesifik:
1. Upload batch sekumpulan file video (diberikan sebagai daftar URL publik) ke ApsaraVideo VOD.
2. Secara otomatis memicu transkoding setelah upload selesai dengan menggunakan kelompok template transkoding yang ditentukan.
3. Setelah transkoding selesai, dapatkan URL pemutaran untuk setiap definisi video.
4. Diperlukan layanan callback HTTP untuk menerima notifikasi event.Proses eksekusi Agent
Fase 1: Membaca llms.txt untuk mencocokkan skenario
Agent mencocokkan skenario dan batasan dalam indeks sebagai berikut:
Kata kunci Quick start → Path dokumen yang cocok:
"Batch URL upload" → media-upload/url-based-upload.md
"Receive async event notifications" → event-notification/event-notification_2.md
"Get playback URL for frontend" → api-reference/get-playback-url.md
"Python SDK initialization" → api-reference/initialization_2.md
"Auto-transcode on upload" → media-processing/workflow.md
Kesalahan umum yang cocok:
#1 Jangan gunakan AccessKey akun root #3 Jangan polling status #5 URL harus di-encode #6 Gunakan backoff QPSFase 2: Memuat dokumentasi terperinci sesuai kebutuhan
Dokumen | Tujuan |
| Parameter dan batasan UploadMediaByURL |
| Mekanisme callback dan jenis event |
| Parameter GetPlayInfo dan struktur respons |
| Metode inisialisasi Python SDK |
| Mekanisme transkoding otomatis saat upload dengan menentukan kelompok template |
Fase 3: Mengekstraksi informasi kunci
Upload batch: UploadMediaByURL
- Asinkron, hanya di Tiongkok (Shanghai), maksimal 20 URL per request
- URL harus di-encode
- Dapat menentukan TemplateGroupId → Transkoding otomatis setelah upload
URL pemutaran: GetPlayInfo
- Prasyarat: Status Video=Normal (setelah transkoding selesai)
- Mengembalikan: PlayInfoList yang berisi PlayURL untuk setiap definisi
Notifikasi event: Callback HTTP POST
- UploadByURLComplete → Upload selesai
- StreamTranscodeComplete → Transkoding definisi tunggal selesai (status siap diputar paling awal)
- TranscodeComplete → Semua transkoding selesai
- Timeout callback adalah 5 detik, dengan maksimal 3 kali percobaan ulangFase 4: Menghasilkan kode
Agent menghasilkan kode inti berdasarkan informasi di atas.
Kode inti yang dihasilkan agent
Upload batch (logika utama): Membaca kredensial dari variabel lingkungan dan menerapkan encoding untuk semua URL.
# Inisialisasi - Baca AK dari variabel lingkungan, jangan hardcode (Kesalahan umum #1)
client = AcsClient(region_id='cn-shanghai', credential=AccessKeyCredential(
os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
))
# Upload batch URL + tentukan kelompok template transkoding (transkode otomatis setelah upload)
request = UploadMediaByURLRequest()
request.set_UploadURLs(','.join([urllib.parse.quote(url, safe='') for url in urls])) # URL harus di-encode!
request.set_UploadMetadatas(json.dumps([{'SourceURL': urllib.parse.quote(u, safe=''), 'Title': f'Video{i}'} for i, u in enumerate(urls)]))
request.set_TemplateGroupId('your_template_group_id') # Kunci: Tentukan ini untuk transkode otomatis setelah upload
response = json.loads(client.do_action_with_exception(request))
# Mengembalikan daftar JobIds. Lacak progres melalui notifikasi event.Layanan callback HTTP (logika utama): Segera mengembalikan status 200 untuk mencegah percobaan ulang di sisi server.
class CallbackHandler(BaseHTTPRequestHandler):
def do_POST(self):
body = json.loads(self.rfile.read(int(self.headers['Content-Length'])))
self.send_response(200) # Harus segera mengembalikan 200; percobaan ulang dipicu setelah timeout 5 detik
self.end_headers()
if body['EventType'] == 'UploadByURLComplete' and body['Status'] == 'success':
print(f"Upload selesai: VideoId={body['VideoId']}, menunggu transkoding...")
elif body['EventType'] == 'TranscodeComplete' and body['Status'] == 'success':
# Semua transkoding selesai -> Dapatkan URL pemutaran
play_info = get_play_info(body['VideoId'])
for stream in play_info['PlayInfoList']['PlayInfo']:
print(f" [{stream['Definition']}] {stream['PlayURL']}")Dapatkan URL pemutaran (logika utama):
request = GetPlayInfoRequest()
request.set_VideoId(video_id)
request.set_Formats('mp4,m3u8')
request.set_AuthTimeout(3600) # URL berlaku selama 1 jam
response = json.loads(client.do_action_with_exception(request))
# response['PlayInfoList']['PlayInfo'] → URL pemutaran untuk setiap definisiHasil eksekusi
Mengirimkan upload batch:
$ python vod_batch_upload.py
[1/2] Menginisialisasi klien VOD... ✓ (wilayah: cn-shanghai)
[2/2] Mengirimkan tugas upload batch (3 video)... ✓
RequestId: 25818875-5F78-4AF6-D7393642CA58****
JobId: ad90a501b1b9**** ← sample1.mp4
JobId: bd81b612c2c8**** ← sample2.mp4
JobId: ce72c723d3d9**** ← sample3.mp4
Langkah selanjutnya dipicu secara otomatis oleh notifikasi event:
UploadByURLComplete → Transkode Otomatis → TranscodeComplete → GetPlayInfoLayanan callback menerima event:
$ python callback_server.py
Layanan callback dimulai: http://0.0.0.0:8080 | Menunggu callback...
[UploadByURLComplete] VideoId=93ab850b**** | Status=success
→ Upload selesai, menunggu transkoding otomatis...
[StreamTranscodeComplete] VideoId=93ab850b**** | Status=success
→ Transkoding definisi LD selesai (siap diputar)
[TranscodeComplete] VideoId=93ab850b**** | Status=success
→ Semua transkoding selesai, mendapatkan URL pemutaran:
[LD] https://vod.example.com/****/sample1-ld.mp4?auth_key=****
[SD] https://vod.example.com/****/sample1-sd.mp4?auth_key=****
[HD] https://vod.example.com/****/sample1-hd.mp4?auth_key=****Visualisasi pengambilan dokumen oleh Agent
Prompt: "Upload batch + transkode + pemutaran"
│
▼
┌── llms.txt (Pencocokan Quick start + Batasan kesalahan umum) ──┐
│ ✓ "Batch URL upload" → media-upload/url-based-upload.md │
│ ✓ "Notifikasi event" → event-notification/event-notification_2.md │
│ ✓ "URL pemutaran" → api-reference/get-playback-url.md │
│ ✓ "Inisialisasi Python" → api-reference/initialization_2.md │
│ ✓ "Transkode otomatis" → media-processing/workflow.md │
│ ✗ #1 Jangan gunakan AK root ✗ #3 Jangan polling ✗ #5 Encode URL ✗ #6 Backoff QPS │
└────────────────────────┬─────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
url-based-upload.md event-notification_2.md get-playback-url.md
- UploadMediaByURL - Daftar jenis event - Parameter request/respons
- URL harus di-encode - Format callback HTTP - Enum definisi
- Batasan wilayah - Kebijakan timeout & retry - QPS=360/s
- Maks 20 URL - Timeout 5 detik - Status=Normal
│ │ │
▼ ▼ ▼
└────► initialization_2.md (konstruktor klien SDK) ◄────┘
│
▼
workflow.md (Transkode otomatis dengan TemplateGroupId)
│
▼
Hasilkan kode lengkap yang dapat dijalankanKeputusan desain utama
Tabel ini merinci keputusan desain utama untuk demo ini beserta dasarnya dalam dokumentasi.
Titik keputusan | Pilihan Agent | Dasar dalam dokumentasi |
Metode upload | UploadMediaByURL | Dokumentasi menentukan API ini untuk upload batch dari daftar URL publik. |
Pemicu transkoding | Tentukan TemplateGroupId saat upload | Dokumentasi menyatakan bahwa menentukan |
Pelacakan status | Callback event HTTP | Kesalahan Umum #3: Hindari polling. |
Waktu mendapatkan URL pemutaran | Setelah TranscodeComplete | Dokumentasi menyatakan bahwa |
Manajemen AccessKey | variabel lingkungan | Kesalahan Umum #1: Jangan hardcode. |
Penanganan URL |
| Kesalahan Umum #5: Harus di-encode. |
Wilayah | cn-shanghai | Dokumentasi menyatakan bahwa upload berbasis URL hanya didukung di wilayah Tiongkok (Shanghai). |
Toleransi kesalahan | Percobaan ulang backoff eksponensial | Kesalahan Umum #6: Backoff untuk pembatasan kecepatan. |
Demo sisi klien: Pemutar Android dan penonton siaran langsung
Demo Android yang dapat dijalankan ini dibangun di atas alur kerja sisi server. Demo ini menunjukkan cara memutar file MP4 dengan kode minimal dan cara mengintegrasikan penonton siaran langsung interaktif menggunakan AUI Kits.
Prompt yang dikirimkan ke agent
Berdasarkan indeks llms sisi klien (di direktori seperti `client-side-player/`, `client-side-upload/`, `client-side-short-video/`), implementasikan aplikasi demo untuk Android.
Persyaratan spesifik:
1. Pilih paket dependensi minimum yang diperlukan untuk memutar URL pemutaran yang dikembalikan oleh respons GetPlayInfo demo sisi server.
2. Di aplikasi yang sama, tambahkan titik masuk lain untuk memasuki penonton siaran langsung interaktif menggunakan AUI Kits (dengan penarikan aliran, bullet screen, like, dan hadiah).
3. Buat nama paket, lisensi, dan domain AppServer dapat dikonfigurasi untuk menghindari hardcoding.Proses eksekusi Agent
Fase 1: Membaca indeks llms sisi klien dan mencocokkan skenario
Hasil pencocokan Quick start:
"Mulai pemutaran VOD di Android" → client-side-player/player-atomic-android.md
"Cara memilih paket/dependensi" → client-side-player/player-overview.md
"Cara mengintegrasikan lisensi" → client-side-player/player-common-license.md
"Penonton siaran langsung interaktif" → client-side-player/player-kits-aui.md
"Kode kesalahan 4400/4013" → client-side-player/player-common-error-codes.md
Kesalahan umum yang cocok:
✗ Menginisialisasi lisensi setelah membuat pemutar → Harus dilakukan di Application.onCreate
✗ Memanggil setSurface sebelum Surface siap → Harus menunggu surfaceCreated
✗ Menggunakan paket fitur lengkap secara default → Pilih paket minimal sesuai skenario
✗ Hardcoding domain AppServer → Abstraksikan ke BuildConfig / gradle.properties
✗ Memanggil PrivateService.init beberapa kali → Inisialisasi hanya sekali di kelas ApplicationFase 2: Memuat dokumentasi terperinci sesuai kebutuhan
Dokumen | Tujuan |
| Keputusan pemilihan paket (BasicLive / UGC / InteractiveLive / Standard) |
| Dependensi Gradle, izin Manifest, obfuscation, dan kode pemutaran minimal |
| Waktu integrasi lisensi dan troubleshooting untuk error 4400/4013 |
| Modul sisi klien AUI Kits dan model kolaborasi AppServer |
| Referensi cepat untuk kegagalan memulai pemutaran |
Fase 3: Mengekstraksi keputusan kunci
Pemilihan paket:
Hanya pemutaran → AliVCSDK_BasicLive
Pemutaran + video pendek → AliVCSDK_UGC
Termasuk co-hosting/siaran langsung interaktif → AliVCSDK_InteractiveLive ← Demo ini memilih yang ini
Fitur lengkap → AliVCSDK_Standard / Premium
Lisensi:
PrivateService.initService(ctx, licenseFile, licenseKey)
Harus diselesaikan sebelum panggilan pertama ke createAliPlayer
AUI Kits:
AppServer + sisi klien; AppServer mengeluarkan Identity Token, Live Room Token, dan IMS Token.
Klien: Tiga modul - AUILiveRoomCore, AUILiveRoomViewer, dan AUIInteraction.Hasil eksekusi
Integrasi pemutar cepat
Dependensi proyek
Di file build.gradle tingkat proyek:
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
}
}Di file build.gradle tingkat aplikasi:
android {
compileSdk 34
defaultConfig {
applicationId "com.example.aliplayer.sample"
minSdk 21
targetSdk 34
ndk { abiFilters "armeabi-v7a", "arm64-v8a" }
buildConfigField "String", "APP_SERVER_HOST",
"\"${project.findProperty('APP_SERVER_HOST') ?: 'https://your-appserver.example.com'}\""
buildConfigField "String", "APP_SERVER_API_PREFIX", "\"/api/v1/live/\""
buildConfigField "String", "LICENSE_KEY",
"\"${project.findProperty('LICENSE_KEY') ?: ''}\""
}
buildFeatures { buildConfig true }
}
dependencies {
implementation 'com.aliyun.aio:AliVCSDK_InteractiveLive:6.0.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.google.code.gson:gson:2.10.1'
}Izin dan obfuscation
Di file AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />Di file proguard-rules.pro:
-keep class com.alivc.**{*;}
-keep class com.aliyun.**{*;}
-keep class com.cicada.**{*;}
-dontwarn com.alivc.**
-dontwarn com.aliyun.**
-dontwarn com.cicada.**Inisialisasi lisensi
public class SampleApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// Tempatkan license.crt di app/src/main/assets/
PrivateService.initService(getApplicationContext(),
"file:///android_asset/license.crt",
BuildConfig.LICENSE_KEY);
}
}Daftarkan di file AndroidManifest.xml:
<application
android:name=".SampleApp"
android:label="@string/app_name"
android:theme="@style/Theme.MaterialComponents.DayNight">
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SimplePlayerActivity" />
</application>UI pemutaran video tunggal
Buat file activity_player.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="220dp"
android:layout_gravity="center" />
</FrameLayout>Buat file SimplePlayerActivity.java:
public class SimplePlayerActivity extends AppCompatActivity {
public static final String EXTRA_PLAY_URL = "play_url";
private AliPlayer aliPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
SurfaceView surfaceView = findViewById(R.id.surfaceView);
aliPlayer = AliPlayerFactory.createAliPlayer(getApplicationContext());
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override public void surfaceCreated(SurfaceHolder h) {
aliPlayer.setSurface(h.getSurface());
}
@Override public void surfaceChanged(SurfaceHolder h, int f, int w, int hh) {
aliPlayer.surfaceChanged();
}
@Override public void surfaceDestroyed(SurfaceHolder h) {
aliPlayer.setSurface(null);
}
});
aliPlayer.setOnPreparedListener(() -> aliPlayer.start());
aliPlayer.setOnErrorListener(err ->
Log.e("AliPlayer", "code=" + err.getCode() + " msg=" + err.getMsg()));
UrlSource source = new UrlSource();
// Sumber: URL pemutaran (dengan auth_key) dari respons GetPlayInfo demo sisi server
String playUrl = getIntent().getStringExtra(EXTRA_PLAY_URL);
source.setUri(playUrl != null ? playUrl : "https://your.cdn/test.mp4");
aliPlayer.setDataSource(source);
aliPlayer.setAutoPlay(true);
aliPlayer.prepare();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (aliPlayer != null) {
aliPlayer.stop();
aliPlayer.release();
}
}
}Jika event prepared dan event frame pertama muncul di log serta SurfaceView merender gambar dengan benar, koneksi dasar telah berhasil.
Penonton siaran langsung AUI Kits
Impor modul AUI Kits
Di file settings.gradle:
include ':app',
':AUILiveRoomCore',
':AUILiveRoomViewer',
':AUIInteraction'Di file build.gradle tingkat aplikasi:
implementation project(':AUILiveRoomCore')
implementation project(':AUILiveRoomViewer')
implementation project(':AUIInteraction')Model kolaborasi AppServer
Klien tidak menyimpan langsung kredensial sensitif seperti IMS Token. Sebagai gantinya, AppServer mengeluarkannya setelah autentikasi. Alur kerja lengkap untuk memasuki ruang siaran langsung adalah sebagai berikut:
[Aplikasi Android] [AppServer]
│ │
│── GET /api/v1/live/viewer/token?roomId=xxx ─►│
│ ├── Autentikasi dan mengeluarkan:
│ │ userId / nick / pullUrl / imsToken
│◄──────── 200 OK + ViewerTokenInfo ───────────┤
│
│── LiveRoomViewerActivity.start(params) ──►(Di dalam AUI Kits)
│ │
│ (AliPlayer untuk penarikan aliran + IMS untuk bullet screen) │Aplikasi Android mengirim permintaan
GET /api/v1/live/viewer/token?roomId=xxxke AppServer dengan status login.AppServer memverifikasi status login dan mengeluarkan
userId,nick,pullUrl, danimsToken.Setelah aplikasi menerima
ViewerTokenInfo, aplikasi memanggilLiveRoomViewerActivity.start(params)untuk memasuki ruang siaran langsung.Secara internal, AUI Kits menggunakan AliPlayer untuk penarikan aliran dan terhubung ke Interactive Messaging Service (IMS) guna mendukung fitur bullet screen, like, dan hadiah.
AppServerClient (implementasi OkHttp)
public class AppServerClient {
public interface Callback {
void onSuccess(ViewerTokenInfo info);
void onFail(String msg);
}
private static final OkHttpClient client = new OkHttpClient();
public static void fetchViewerToken(String roomId, Callback cb) {
HttpUrl url = HttpUrl.parse(
BuildConfig.APP_SERVER_HOST + BuildConfig.APP_SERVER_API_PREFIX + "viewer/token")
.newBuilder()
.addQueryParameter("roomId", roomId)
.build();
Request req = new Request.Builder()
.url(url)
.header("Authorization", "Bearer " + LoginManager.getToken())
.build();
client.newCall(req).enqueue(new okhttp3.Callback() {
@Override public void onFailure(Call call, IOException e) {
cb.onFail(e.getMessage());
}
@Override public void onResponse(Call call, Response resp) throws IOException {
if (!resp.isSuccessful() || resp.body() == null) {
cb.onFail("HTTP " + resp.code());
return;
}
ViewerTokenInfo info = new Gson().fromJson(
resp.body().string(), ViewerTokenInfo.class);
cb.onSuccess(info);
}
});
}
}
public class ViewerTokenInfo {
public String roomId;
public String userId;
public String nick;
public String pullUrl; // Salah satu dari rtmp, flv, m3u8, atau artc
public String imsToken; // Token Interactive Messaging Service (IMS)
}Gabungkan dua entri demo
Buat file activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="24dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:id="@+id/btnSimple"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Simple Playback" />
<Button android:id="@+id/btnLiveRoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Interactive Live Viewer" />
</LinearLayout>Buat file MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnSimple).setOnClickListener(v -> {
Intent intent = new Intent(this, SimplePlayerActivity.class);
// Di aplikasi nyata, berikan URL pemutaran dari respons GetPlayInfo demo sisi server di sini
intent.putExtra(SimplePlayerActivity.EXTRA_PLAY_URL,
"https://vod.example.com/****/sample1-hd.mp4?auth_key=****");
startActivity(intent);
});
findViewById(R.id.btnLiveRoom).setOnClickListener(v -> enterRoom("demo_room_001"));
}
private void enterRoom(String roomId) {
AppServerClient.fetchViewerToken(roomId, new AppServerClient.Callback() {
@Override public void onSuccess(ViewerTokenInfo info) {
LiveRoomEnterParams params = new LiveRoomEnterParams.Builder()
.roomId(info.roomId)
.userId(info.userId)
.userNick(info.nick)
.pullUrl(info.pullUrl)
.imsToken(info.imsToken)
.build();
LiveRoomViewerActivity.start(MainActivity.this, params);
}
@Override public void onFail(String msg) {
Toast.makeText(MainActivity.this, "Gagal memasuki ruang: " + msg, Toast.LENGTH_LONG).show();
}
});
}
}Daftar periksa verifikasi
Setelah menjalankan demo, verifikasi perilaku UI dan output log berikut:
Klik Simple Playback:
SimplePlayerActivitydimulai, dan video diputar dengan lancar diSurfaceViewtanpa layar hitam.Klik Interactive Live Streaming Viewer:
LiveRoomViewerActivityAUI Kits diluncurkan; AliPlayer menampilkan feed video host; panel bullet screen, like, dan hadiah di pojok kanan bawah berfungsi.Log logcat utama: Kemunculan bersamaan
AliPlayer: prepared,AliPlayer: first frame, danIMS: connectedmenunjukkan bahwa penarikan aliran dan interaksi sudah siap.
Visualisasi pengambilan dokumen oleh Agent
Prompt: "Pemutaran Android + masuk ruang siaran langsung interaktif"
│
▼
┌── Client-side llms.txt (Quick start + Kesalahan umum) ────────┐
│ ✓ "Pemutaran Android" → player-atomic-android.md │
│ ✓ "Cara memilih paket" → player-overview.md │
│ ✓ "Lisensi" → player-common-license.md │
│ ✓ "Interaktif AUI Kits" → player-kits-aui.md │
│ ✓ "Kode kesalahan 4400/4013"→ player-common-error-codes.md │
│ ✗ Lisensi harus diinisialisasi sebelum pembuatan pemutar │
│ ✗ Jangan panggil setSurface sebelum Surface siap │
│ ✗ Jangan gunakan paket fitur lengkap secara default │
│ ✗ Jangan hardcode domain AppServer │
│ ✗ Panggil PrivateService.init hanya sekali di Application │
└────────────────────────┬────────────────────────────────────┘
│
┌─────────────┬────────┴─────────┬─────────────┐
▼ ▼ ▼ ▼
player- player-atomic- player-common- player-kits-aui.md
overview.md android.md license.md - Kolaborasi AppServer
- Matriks paket - dependensi gradle - PrivateService - Tiga jenis token
- Peta skenario - izin Manifest - 4400/4013 - Rincian modul
- Ukuran SDK - kode pemutaran - Package/BundleID - Integrasi klien 4 langkah
└─────────────┴────────┬─────────┴─────────────┘
│
▼
player-common-error-codes.md
(Panduan untuk 4400/4013/4034/4036)
│
▼
Hasilkan Demo Android lengkap yang dapat dijalankanKeputusan desain utama
Titik keputusan | Pilihan Agent | Dasar dalam dokumentasi |
Bundel SDK | AliVCSDK_InteractiveLive | Matriks pemilihan di |
Waktu lisensi | Application.onCreate | player-common-license.md: Harus dipanggil sebelum |
Pengikatan Permukaan |
| Templat standar |
Domain AppServer | BuildConfig + gradle.properties | Kesalahan Umum: Jangan hardcode. |
Integrasi sisi server | Gunakan kembali URL pemutaran dari respons GetPlayInfo demo sisi server | Hal ini memastikan konsistensi end-to-end antara demo sisi server dan sisi klien. |
Penonton siaran langsung interaktif | Tiga modul AUI Kits (Core / Viewer / Interaction) | player-kits-aui.md: Panduan integrasi sisi klien utama. |
Penanganan error |
|
|
Daftar periksa pra-peluncuran (Android)
Dimensi | Item periksa |
Lisensi | Lisensi pengujian dan produksi telah diajukan dan dikonfigurasi di BuildConfig masing-masing. |
Ukuran paket |
|
Memulai pemutaran | Listener untuk 4400/4013/4034/4036 diimplementasikan untuk pemantauan. |
Ruang siaran langsung | Pembaruan otomatis untuk IMS Token yang kadaluarsa diimplementasikan; AppServer telah mengaktifkan HTTPS dan CORS. |
Privasi | Izin untuk perekaman audio, akses jaringan, dan pembacaan media semuanya dinyatakan dalam kebijakan privasi. |
Rilis canary | Pertama, rilis versi baru ke 5% pengguna. Pantau waktu frame pertama dan tingkat kegagalan selama 48 jam sebelum peluncuran penuh. |
Pemantauan | Aktifkan layanan pemantauan kualitas pemutar (QoS) dan pelacakan titik tunggal Alibaba Cloud. |
Struktur direktori akhir
AliPlayerSampleApp/
├── app/
│ ├── src/main/
│ │ ├── assets/license.crt
│ │ ├── java/com/example/aliplayer/sample/
│ │ │ ├── SampleApp.java
│ │ │ ├── MainActivity.java
│ │ │ ├── SimplePlayerActivity.java ← Pemutaran Sederhana
│ │ │ ├── AppServerClient.java ← Siaran Langsung Interaktif
│ │ │ ├── ViewerTokenInfo.java
│ │ │ └── LoginManager.java
│ │ └── AndroidManifest.xml
│ └── build.gradle
├── AUILiveRoomCore/ ← Siaran Langsung Interaktif
├── AUILiveRoomViewer/ ← Siaran Langsung Interaktif
├── AUIInteraction/ ← Siaran Langsung Interaktif
├── gradle.properties (APP_SERVER_HOST / LICENSE_KEY)
├── settings.gradle
└── build.gradleDemo sisi server dan sisi klien kini membentuk alur kerja lengkap yang tertutup. Alur kerja ini, yang dihasilkan oleh Agent menggunakan indeks llms.txt, mencakup pengunggahan video, transkoding otomatis, pengambilan URL pemutaran, pemutaran video dasar, dan penonton siaran langsung interaktif menggunakan AUI Kits.
Apendiks: Pemilihan dan pemeriksaan mandiri Agent
Apendiks ini ditujukan bagi developer yang belum menggunakan atau menginstal Coding Agent.
Kapan menggunakan Coding Agent
Kasus penggunaan | Apakah diperlukan? |
Anda ingin AI membaca | Ya |
Anda hanya ingin membaca dokumen ini untuk memahami arsitektur, lalu menyalin dan memodifikasi kode secara manual. | Tidak. Browser web sudah cukup. |
Anda ingin AI secara langsung menambah, menghapus, dan memodifikasi file di repositori lokal Anda serta menjalankan perintah untuk memvalidasi perubahan. | Ya |
Opsi yang direkomendasikan
Kategori | Nama | Jenis | Deskripsi |
Direkomendasikan | Qoder / Cursor / Claude Code | IDE Desktop atau CLI | Secara native mendukung pengambilan dokumen panjang menggunakan indeks bergaya |
Lainnya | - | - | Coding Agent apa pun yang dapat mengakses URL, menulis file lokal, dan memanggil perintah shell. |
Gunakan tautan instalasi dari situs web resmi produk. Hindari menggunakan image pihak ketiga.
Pemeriksaan mandiri minimum
Kirimkan prompt berikut ke Coding Agent Anda untuk memverifikasi kemampuannya:
Silakan baca https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/vod/llms/llms.txt,
dan beri tahu saya:
1. Berapa banyak modul tingkat atas dalam indeks ini? Apa saja?
2. Sub-dokumen mana yang terlibat dalam alur kerja "upload batch + transkoding otomatis + dapatkan URL pemutaran audio/video"? Sebutkan path relatifnya.
3. Di bagian "Common mistakes to avoid", apa catatan yang terkait dengan "AccessKey"?Jawaban yang diharapkan:
Menyebutkan dengan benar modul tingkat atas dari
llms.txt.Memberikan daftar sub-dokumen yang sebagian besar konsisten dengan tabel pemuatan sesuai kebutuhan dalam demo sisi server (upload media, notifikasi event, dapatkan URL pemutaran audio/video, inisialisasi Python SDK, alur kerja pemrosesan media).
Menyatakan dengan jelas: Jangan gunakan AccessKey Akun Alibaba Cloud. Gunakan RAM user sebagai gantinya.
Agent yang lulus ketiga pemeriksaan ini siap untuk demo dalam dokumen ini.