WanduraDocsBeta
BetaDocs đang ở bản beta và còn thay đổi. Thấy chỗ sai, khó hiểu hoặc còn thiếu? Hãy cho chúng tôi biết.
Bạn đang đọc một bản tài liệu cũ: v1 · Sang bản mới nhất (v2)
Lịch sử thay đổi

Lịch sử: Catalog

Mọi lần sửa trang này, mới nhất ở trên. Mở từng mục để xem đã đổi gì.

← Catalog

  1. 03/10/2026 · +8 −8 dòng
    Xem thay đổi
    ⋯
      - Với tập, dùng `poster_url` (URL `https` tải được, hoặc `null`, khi đó lui về poster của phim). `poster_uri` là tham chiếu nội bộ, không phải URL tải được.
      
    - > **Đang triển khai.** Mỗi phim còn có `images`, ảnh của phim theo loại, mỗi phần tử `{ "kind", "url", "width", "height" }`:
    - >
    - > | `kind` | Là gì | `width` / `height` |
    - > |---|---|---|
    - > | `poster_3_4` | Poster thẻ tỉ lệ 3:4 | pixel, đo từ chính file |
    - > | `cover_9_16` | Ảnh bìa toàn màn hình 9:16, cùng ảnh với `poster_url` | tạm thời là `null` (chưa ghi kích thước) |
    - >
    - > Loại Wandura chưa có thì không có mặt, nên mảng có thể rỗng; mảng không bao giờ chứa phần tử `null`. Mọi `url` là URL `https` tuyệt đối trên host của Wandura, tải thẳng được. Có thể có loại mới: bỏ qua loại bạn không biết. `poster_url` giữ nguyên như cũ.
    + Mỗi phim còn có `images`, ảnh của phim theo loại, mỗi phần tử `{ "kind", "url", "width", "height" }`:
      
    + | `kind` | Là gì | `width` / `height` |
    + |---|---|---|
    + | `poster_3_4` | Poster thẻ tỉ lệ 3:4 | pixel, đo từ chính file |
    + | `cover_9_16` | Ảnh bìa toàn màn hình 9:16, cùng ảnh với `poster_url` | tạm thời là `null` (chưa ghi kích thước) |
    + 
    + Loại Wandura chưa có thì không có mặt, nên mảng có thể rỗng; mảng không bao giờ chứa phần tử `null`. Mọi `url` là URL `https` tuyệt đối trên host của Wandura, tải thẳng được. Có thể có loại mới: bỏ qua loại bạn không biết. `poster_url` giữ nguyên như cũ.
    + 
      ## Độ mới {#keeping-your-copy-fresh}
      
    ⋯
  2. 03/10/2026 · +9 −0 dòng
    Xem thay đổi
    ⋯
      - Với tập, dùng `poster_url` (URL `https` tải được, hoặc `null`, khi đó lui về poster của phim). `poster_uri` là tham chiếu nội bộ, không phải URL tải được.
      
    + > **Đang triển khai.** Mỗi phim còn có `images`, ảnh của phim theo loại, mỗi phần tử `{ "kind", "url", "width", "height" }`:
    + >
    + > | `kind` | Là gì | `width` / `height` |
    + > |---|---|---|
    + > | `poster_3_4` | Poster thẻ tỉ lệ 3:4 | pixel, đo từ chính file |
    + > | `cover_9_16` | Ảnh bìa toàn màn hình 9:16, cùng ảnh với `poster_url` | tạm thời là `null` (chưa ghi kích thước) |
    + >
    + > Loại Wandura chưa có thì không có mặt, nên mảng có thể rỗng; mảng không bao giờ chứa phần tử `null`. Mọi `url` là URL `https` tuyệt đối trên host của Wandura, tải thẳng được. Có thể có loại mới: bỏ qua loại bạn không biết. `poster_url` giữ nguyên như cũ.
    + 
      ## Độ mới {#keeping-your-copy-fresh}
      
    ⋯
  3. 02/10/2026 · +36 −40 dòng
    Xem thay đổi
      # Catalog
      
    - Catalog là danh sách phim và tập mà tổ chức của bạn được phép stream ngay lúc này. Catalog được thiết kế để là danh sách phim duy nhất app của bạn cần: nó mang thứ tự hiển thị, quy tắc tập miễn phí, facet thể loại và cờ sẵn sàng cho từng tập, nên bạn không phải tự duy trì những thứ này.
    - 
    - ## Catalog chứa gì
    + > **TL;DR** — `GET /catalog` liệt kê mọi phim và tập mà tổ chức của bạn được stream ngay lúc này, kèm thứ tự hiển thị, quy tắc tập miễn phí và cờ sẵn sàng cho từng tập. Chỉ có metadata, không bao giờ có URL video. Lấy cả catalog một lần, hoặc theo trang bằng `limit` và `cursor`. Đây là danh sách phim duy nhất app của bạn cần; request xin vé đằng nào cũng kiểm tra lại mọi thứ.
      
    - `GET /api/delivery/v1/catalog` trả về một phim khi tất cả các điều kiện sau đều đúng tại thời điểm request:
    + ## Catalog chứa gì {#what-is-in-the-catalog}
      
    - - Tổ chức của bạn có giấy phép streaming cho phim, và giấy phép đó đang hoạt động.
    - - Hôm nay nằm trong khung thời gian của giấy phép. Khung thời gian tính theo ngày trọn vẹn theo UTC, bao gồm cả ngày đầu và ngày cuối.
    - - Phim đã được publish.
    + Một phim được liệt kê khi, tại thời điểm request:
      
    - Với những phim đó, catalog trả về mọi tập đã publish. Phim còn đang sản xuất, và bản dựng thô (review cut) được chia sẻ để bạn góp ý, không bao giờ xuất hiện trong catalog và không phát được qua API.
    + - tổ chức của bạn có giấy phép streaming cho phim, và giấy phép đó đang hoạt động;
    + - hôm nay (UTC) nằm trong khung thời gian của giấy phép, tính theo ngày trọn vẹn, gồm cả ngày đầu và ngày cuối;
    + - phim đã được publish.
      
    - Catalog chỉ chứa metadata. Nó không bao giờ chứa URL video; bạn xin playback cho từng tập bằng [`POST /playback`](playback.md).
    + Với những phim đó, catalog liệt kê mọi tập đã publish, cộng một dòng placeholder cho mỗi tập dự kiến chưa publish. Phim còn đang sản xuất và bản dựng thô (review cut) không bao giờ xuất hiện và không phát được qua API. Response rỗng (`"films": []`) nghĩa là lúc này tổ chức của bạn không có giấy phép nào đang hoạt động.
      
    - ## Cấu trúc response
    + ## Cấu trúc response {#response-shape}
      
    - Response có hai mảng phẳng, `films` và `episodes`. Nối chúng theo `episodes[].film_id` = `films[].id`. Danh sách trường đầy đủ nằm trong [tài liệu tham chiếu catalog](../reference/catalog.md).
    + Hai mảng phẳng, `films` và `episodes`; nối chúng theo `episodes[].film_id` = `films[].id`. Response còn mang `links` (`self`, `next`, `playback`, `config`). Mọi trường: [Lấy catalog được cấp phép](../reference/catalog.md).
      
    - Toàn bộ catalog trả về trong một response. Không có pagination.
    + ## Trang {#pages}
      
    - ## Thứ tự
    + Không có `limit` hay `cursor` thì bạn nhận cả catalog trong một response. Có `limit` (1–200 phim) thì bạn nhận một trang phim kèm **mọi** tập của chúng, cộng `next_cursor` và `links.next`; gửi lại cursor nguyên văn cho tới khi nó là `null`. Các trang **không** phải một ảnh chụp nhất quán: luật đồng bộ an toàn nằm ở [Hành vi chuẩn của API · Pagination](../reference/behaviour.md#pagination), còn code nằm ở [Đồng bộ catalog](../guides/catalog-sync.md).
      
    - `films` được sắp theo `display_order`, nhỏ nhất trước. Hãy hiển thị phim đúng theo thứ tự nhận được. Wandura chỉnh thứ tự này, nên đừng giữ bảng thứ tự riêng.
    + ## Thứ tự {#order}
      
    - `episodes` được nhóm theo film ID, rồi sắp theo `episode_no`. Các nhóm không theo thứ tự hiển thị, nên hãy lấy thứ tự phim từ `films`.
    + `films` được sắp theo `display_order`, nhỏ nhất trước, và giữ thứ tự đó qua các trang. Hiển thị phim đúng thứ tự này; Wandura chỉnh thứ tự, nên đừng giữ bảng thứ tự riêng. `episodes` được nhóm theo phim, rồi theo `episode_no`; hãy lấy thứ tự phim từ `films`.
      
    - ## Tập miễn phí và tập trả phí
    + ## Tập miễn phí và tập trả phí {#free-and-paid-episodes}
      
    - Tập có `episode_no` nhỏ hơn hoặc bằng `free_until_episode` của phim là miễn phí; các tập còn lại là trả phí. Giá trị này khác nhau giữa các phim và có thể thay đổi, nên hãy đọc từ catalog thay vì hard-code. `0` nghĩa là không có tập miễn phí; `null` nghĩa là phim chưa được đặt số này, nên hãy coi mọi tập là trả phí.
    + Tập có `episode_no` ≤ `free_until_episode` của phim là miễn phí; các tập còn lại là trả phí. `0` nghĩa là không có tập miễn phí; `null` nghĩa là chưa đặt số này, nên hãy coi mọi tập là trả phí. Giá trị khác nhau giữa các phim và có thể thay đổi: đọc lại ở mỗi lần đồng bộ.
      
      ## Tập dự kiến {#planned-episodes}
      
    - `planned_episodes` là số tập phim sẽ có. Khi một số tập chưa được publish, catalog vẫn có một dòng cho mỗi số tập còn thiếu để bạn hiển thị ô "sắp ra mắt". Các dòng placeholder này có:
    + `planned_episodes` là số tập phim sẽ có. Với mỗi tập chưa publish, catalog có một dòng placeholder để bạn hiển thị "sắp ra mắt":
      
      | Trường | Giá trị |
    ⋯
      | `status` | `"planned"` |
      | `stream_ready` | `false` |
    - | `title`, `synopsis`, `duration_ms`, `poster_uri` | `null` |
    - 
    - Không bao giờ gửi dòng placeholder tới `POST /playback`: nó không có episode ID. Nếu phim có nhiều tập đã publish hơn `planned_episodes`, tất cả vẫn được trả về. Khi `planned_episodes` là `null`, phim không có dòng placeholder nào.
    - 
    - ## Trạng thái sẵn sàng: `stream_ready`
    + | `title`, `synopsis`, `duration_ms`, `poster_uri`, `poster_url` | `null` |
      
    - `stream_ready: true` nghĩa là đã có bản mã hoá của tập và `POST /playback` có thể cấp vé cho tập đó. Hãy làm mờ hoặc ẩn các tập có giá trị `false`, thay vì để người xem chạm vào rồi gặp lỗi.
    + Không bao giờ gửi dòng placeholder tới `POST /playback`: nó không có ID. Khi `planned_episodes` là `null`, không có dòng placeholder nào.
      
    - Cờ này là ảnh chụp tại lúc bạn tải catalog. `POST /playback` kiểm tra lại giấy phép và tập mỗi lần, và câu trả lời của nó mới là câu trả lời có giá trị. Nhận `not_ready` cho một tập từng có `stream_ready: true` là bình thường, ví dụ sau khi một phim bị rút.
    + ## Trạng thái sẵn sàng: `stream_ready` {#readiness-stream-ready}
      
    - ## Facet thể loại
    + `true` nghĩa là lúc này có thể cấp vé cho tập. Làm mờ hoặc ẩn các tập có giá trị `false`. Cờ này là ảnh chụp tại lúc bạn tải catalog: request xin vé kiểm tra lại, và câu trả lời của nó mới có giá trị. Nhận `not_ready` cho một tập từng có `stream_ready: true` là bình thường, ví dụ ngay sau khi phim bị rút.
      
    - Mỗi phim mang ba facet tuỳ chọn cho màn hình duyệt và bộ lọc. `null` nghĩa là phim chưa được phân loại; hãy hiển thị phim mà không có facet đó thay vì đoán.
    + ## Facet thể loại {#genre-facets}
      
    - | Trường | Giá trị có thể có |
    + | Trường | Giá trị (`null` = chưa phân loại; có thể có giá trị mới) |
      |---|---|
    - | `audience` | `women`, `men`, `lgbtq`, hoặc `null` |
    - | `form` | `live_action`, `anime`, hoặc `null` |
    - | `setting` | `modern`, `city`, `fantasy`, `campus`, `palace`, hoặc `null` |
    + | `audience` | `women`, `men`, `lgbtq` |
    + | `form` | `live_action`, `anime` |
    + | `setting` | `modern`, `city`, `fantasy`, `campus`, `palace` |
      
    - Phim còn có `genres`, một mảng nhãn thể loại dạng văn bản tự do, và `language`.
    + Phim còn có `genres` (nhãn văn bản tự do) và `language` (văn bản tự do: hiển thị, đừng parse).
      
    - ## Văn bản và ảnh
    + ## Văn bản và ảnh {#text-and-artwork}
      
    - - `synopsis_short` dùng cho thẻ, `synopsis_full` dùng cho trang chi tiết. Độ dài khác nhau giữa các phim, nên hãy giới hạn (clamp) văn bản trong UI. `synopsis_full` có thể là `null`.
    - - `episodes[].synopsis` có thể là `null`. Khi đó đừng hiển thị gì.
    - - `poster_url` (phim) và `poster_uri` (tập) có thể là `null` trong lúc ảnh đang được chuẩn bị. Hãy hiển thị ảnh placeholder.
    + - `synopsis_short` dùng cho thẻ, `synopsis_full` dùng cho trang chi tiết; độ dài khác nhau, hãy clamp. Cả hai đều có thể là `null`.
    + - `poster_url` (phim) có thể là `null` trong lúc ảnh đang được chuẩn bị: hiển thị ảnh placeholder.
    + - Với tập, dùng `poster_url` (URL `https` tải được, hoặc `null`, khi đó lui về poster của phim). `poster_uri` là tham chiếu nội bộ, không phải URL tải được.
      
    - ## Giữ bản sao luôn mới
    + ## Độ mới {#keeping-your-copy-fresh}
      
    - Cache catalog trên server và làm mới theo lịch, thay vì gọi API mỗi lần mở app. Giấy phép hết hạn hoặc phim bị rút sẽ biến mất khỏi response kế tiếp; hãy gỡ mọi thứ không còn được liệt kê.
    + Một thay đổi phía Wandura (publish, rút phim, giấy phép bắt đầu hay kết thúc) xuất hiện trong catalog trong vòng 30 giây. Mọi mốc thời gian: [Hành vi chuẩn của API · Độ mới](../reference/behaviour.md#freshness). Đồng bộ mỗi 15–60 phút từ server của bạn; không bao giờ gọi catalog mỗi lần mở app.
      
    - Response catalog có thể cũ tối đa 30 giây. Phim hoặc tập vừa công bố hay vừa rút, `stream_ready` vừa đổi, giấy phép vừa cấp, vừa treo hay vừa hết hạn sẽ hiện đúng trong catalog sau tối đa 30 giây. Wandura chạy nhiều server, mỗi server giữ bản riêng, nên hai lần gọi trong 30 giây đó có thể trả hai bản khác nhau.
    + ## Liên quan {#related}
      
    - Catalog có bộ đếm rate limit riêng, tách khỏi playback và creatives. Xem [Rate limit](rate-limits.md).
    + - [Đồng bộ catalog](../guides/catalog-sync.md)
    + - [Lấy catalog được cấp phép](../reference/catalog.md)
    + - [Khi quyền kết thúc](../production/rights-end.md)
  4. 02/10/2026 · +2 −0 dòng
    Xem thay đổi
    ⋯
      Cache catalog trên server và làm mới theo lịch, thay vì gọi API mỗi lần mở app. Giấy phép hết hạn hoặc phim bị rút sẽ biến mất khỏi response kế tiếp; hãy gỡ mọi thứ không còn được liệt kê.
      
    + Response catalog có thể cũ tối đa 30 giây. Phim hoặc tập vừa công bố hay vừa rút, `stream_ready` vừa đổi, giấy phép vừa cấp, vừa treo hay vừa hết hạn sẽ hiện đúng trong catalog sau tối đa 30 giây. Wandura chạy nhiều server, mỗi server giữ bản riêng, nên hai lần gọi trong 30 giây đó có thể trả hai bản khác nhau.
    + 
      Catalog có bộ đếm rate limit riêng, tách khỏi playback và creatives. Xem [Rate limit](rate-limits.md).
  5. 01/10/2026 · +1 −1 dòng
    Xem thay đổi
    ⋯
      Cache catalog trên server và làm mới theo lịch, thay vì gọi API mỗi lần mở app. Giấy phép hết hạn hoặc phim bị rút sẽ biến mất khỏi response kế tiếp; hãy gỡ mọi thứ không còn được liệt kê.
      
    - Endpoint catalog và creatives dùng chung một bộ đếm rate limit. Xem [Rate limit](rate-limits.md).
    + Catalog có bộ đếm rate limit riêng, tách khỏi playback và creatives. Xem [Rate limit](rate-limits.md).
  6. 01/10/2026 · +2 −2 dòng
    Xem thay đổi
    ⋯
      ## Tập miễn phí và tập trả phí
      
    - Tập có `episode_no` nhỏ hơn hoặc bằng `free_until_episode` của phim là miễn phí; các tập còn lại là trả phí. Giá trị này khác nhau giữa các phim và có thể thay đổi, nên hãy đọc từ catalog thay vì hard-code.
    + Tập có `episode_no` nhỏ hơn hoặc bằng `free_until_episode` của phim là miễn phí; các tập còn lại là trả phí. Giá trị này khác nhau giữa các phim và có thể thay đổi, nên hãy đọc từ catalog thay vì hard-code. `0` nghĩa là không có tập miễn phí; `null` nghĩa là phim chưa được đặt số này, nên hãy coi mọi tập là trả phí.
      
      ## Tập dự kiến {#planned-episodes}
    ⋯
      | `title`, `synopsis`, `duration_ms`, `poster_uri` | `null` |
      
    - Không bao giờ gửi dòng placeholder tới `POST /playback`: nó không có episode ID. Nếu phim có nhiều tập đã publish hơn `planned_episodes`, tất cả vẫn được trả về.
    + Không bao giờ gửi dòng placeholder tới `POST /playback`: nó không có episode ID. Nếu phim có nhiều tập đã publish hơn `planned_episodes`, tất cả vẫn được trả về. Khi `planned_episodes` là `null`, phim không có dòng placeholder nào.
      
      ## Trạng thái sẵn sàng: `stream_ready`
    ⋯
  7. 29/09/2026 · Tạo trang
↑↓ chọnEnter mởEsc đóng

Gửi góp ý

Góp ý được gửi thẳng tới đội Wandura, kèm địa chỉ trang này.

0 / 4000