Trả lời theo yêu cầu
Đây là bản dịch. Bản tiếng Anh là bản có giá trị: nếu hai bản khác nhau, hãy làm theo bản tiếng Anh. Bản dịch chỉ được cung cấp để tiện theo dõi. Đọc trang này bằng tiếng Anh
Mọi thứ trong Gửi danh mục đều giả định một danh mục đang tồn tại. Có những nguồn không có: thứ chúng có là khả năng tìm một thứ rồi đi lấy nó về. Một provider như vậy không thể phản chiếu danh mục của mình cho chúng tôi, vì danh mục của nó là cả internet.
Nên nó trả lời các câu hỏi. Có ba câu:
- Tìm kiếm (search). “Bạn có gì cho những từ này không?”
- Nghe thử (preview). “Có người muốn nghe một đoạn của bài đó trước khi quyết định.”
- Tải về (fetch). “Có người đã xếp bài đó. Hãy đi biến nó thành thật.”
Chúng tôi vẫn không bao giờ gọi đến bạn. Đó là toàn bộ tiền đề của việc đẩy lên, và không gì ở đây thay đổi nó: cả ba đều là job mà bạn tự đến nhận. Nếu máy của bạn đang ngủ, phòng đơn giản là không có câu trả lời, cùng kiểu hỏng như một bridge đang tắt.
Chỉ những provider báo canSearchRemotely mới được hỏi, và nghe thử là một lựa chọn riêng thêm vào trên đó. Một bridge không triển khai bất cứ phần nào trong này sẽ không bao giờ được giao job và không cần thay đổi gì.
Nhận việc
GET https://api.lets.dj/providers/jobs?max=4
Authorization: Bearer <sync token>
{
"jobs": [
{ "id": "j97…", "kind": "search", "term": "diem xua" },
{ "id": "j57…", "kind": "fetch", "externalId": "abc123", "position": 3 },
{ "id": "j21…", "kind": "preview", "externalId": "def456" }
],
"cancelled": ["j91…"]
}
Hãy thăm dò khoảng một lần mỗi giây. Trả về một job nghĩa là nó được giao cho bạn. max là số bạn sẽ nhận, từ 1 đến 20, và là bốn khi bạn bỏ trống; số lớn hơn bị cắt còn 20. job.id là một giá trị mờ: chỉ dùng nó để báo cáo lại.
Các job đến theo một thứ tự cố định, và bạn nên giữ nguyên. Trước hết là fetch, position thấp nhất trước. Sau đó là search, cũ nhất trước. Rồi đến preview, cũ nhất trước.
position là vị trí của bài đó trong hàng chờ mà nó được tạo ra cho. Hãy lấy cái thấp nhất trước. Nếu không, ba bài xếp cùng một lượt sẽ đến theo thứ tự các cú chạm, và cả phòng chờ nhầm bài.
Một preview không mang position, và nên được lấy sau cùng. Bài kế tiếp của ai đó luôn được ưu tiên hơn việc xem lướt của người khác.
cancelled liệt kê các job bạn đang giữ mà không ai còn chờ nữa: bài đã bị gỡ, hoặc người xếp nó đã rời đi. Hãy dừng việc đó lại. Chúng chỉ được báo một lần, nên hãy xử lý ngay khi thấy.
Một job đã nhận mà im lặng một phút sẽ được giao lại cho nơi khác, với giả định bạn đã khởi động lại. Mỗi báo cáo bạn gửi được tính là không im lặng. Hãy hoàn tất hoặc báo thất bại thay vì bỏ ngang.
Báo cáo lại
POST https://api.lets.dj/providers/jobs/<id>
Authorization: Bearer <sync token>
Content-Type: application/json
Trong khi làm việc, thường xuyên theo mức hữu ích và không quá vài giây một lần:
{ "state": "working", "phase": "downloading", "percent": 42 }
phase tồn tại vì phần trăm nói dối: tải hai luồng rồi ghép lại tạo ra một thanh tiến độ bị lùi, trừ khi bạn nói được điều gì đã thay đổi. percent là tùy chọn. Hãy bỏ nó đi thay vì bịa ra một con số. Nó là một số từ 0 đến 100, và thứ được hiển thị bị giới hạn trong khoảng đó.
Các phase là một tập có thứ tự, và bạn không bao giờ được đi lùi trong đó:
starting → downloading → converting → verifying → finalizing
Bỏ qua cái nào bạn không làm. Không gửi gì cả nếu bạn không muốn nói. Nhưng một căn phòng đã được báo là một bài đang finalizing rồi lại thấy downloading sẽ biết rằng những từ ấy chẳng có nghĩa gì, điều còn tệ hơn là chưa từng có chúng, vì nó cũng không còn tin được thanh tiến độ bên cạnh.
Phía chúng tôi không kiểm tra điều này. phase được lưu đúng như văn bản bạn gửi, và thứ tự là việc của bạn giữ. Thứ một người nhìn thấy không phải từ của bạn mà là từ của chúng tôi: trong khi ai đó chờ một bản nghe thử, starting thành “Finding…”, downloading thành “Loading…”, retrying thành “Retrying…”, và converting, verifying, finalizing đều thành “Almost…”. Một từ ngoài bộ từ vựng được hiện thành “Loading…” chung chung chứ không hiện nguyên từ đó.
Cái bẫy là công việc phụ. Việc lấy ảnh bìa hay siêu dữ liệu thường diễn ra trước media và có thể báo tiến độ riêng; nếu nó bị gán một phase nghe như về sau, hoặc phần trăm của nó bị nhầm với của media, dãy phase sẽ chạy ngược đúng theo cách quy tắc này cấm. Hoặc im lặng trong lúc đó, hoặc gọi nó là starting.
Có một từ nằm ngoài dãy: retrying, cho một lần thử đã thất bại và đang được làm lại. Nó có thể xuất hiện ở bất kỳ lúc nào, và downloading có thể theo sau nó từ số không. Đó là trường hợp duy nhất mà thanh tiến độ được phép bắt đầu lại một cách trung thực, và gọi tên nó tốt hơn một phần trăm tự nhiên tụt xuống.
Hoàn tất một search nghĩa là trả về các ứng viên, tối đa 50 (phần dư bị bỏ):
{
"state": "done",
"results": [
{
"externalId": "abc123",
"title": "Diễm Xưa",
"artist": "Trịnh Công Sơn",
"durationSeconds": 254,
"thumbnailUrl": "https://…"
}
]
}
Đây không phải là mục danh mục, và không có gì được lưu thành track cho đến khi ai đó chọn một cái. Một ứng viên không có externalId hoặc không có title không thể được chọn hay tải về, và bị bỏ. Một ứng viên đã có trong thư viện như một track bình thường bị ẩn khỏi người đã hỏi, vì mục đích của việc hỏi lần hai là tìm thứ thư viện chưa có. externalId phải đúng là id bạn sẽ báo cho track đó trong một lần đồng bộ, nếu không việc tải về tiếp theo sẽ hỏi bạn một thứ bạn không khớp được.
Hoàn tất một fetch gồm hai bước, theo thứ tự này: đồng bộ track mới trước, rồi báo job đã xong. Lần đồng bộ là thứ biến bài hát thành thật; báo trước sẽ để lại một mục hàng chờ trỏ tới một track chưa tồn tại. Hãy gửi lần đồng bộ đó với final: false. Một lần đồng bộ bỏ trống final là một lần thay thế, và việc thay thế bằng một track duy nhất sẽ xóa phần còn lại của thư viện bạn.
{ "state": "done" }
Hoàn tất một preview là cùng một dòng đơn đó, và cố ý không kèm một lần đồng bộ: một preview không phải mục danh mục và không bao giờ được hiện như vậy. Báo nó xong chỉ có nghĩa là các byte mô tả trong Nghe thử giờ có thể được phát.
Và khi nó không làm được:
{ "state": "failed", "error": "video is unavailable in this region" }
Hãy nói điều thực sự đã xảy ra. Người đã xếp bài được cho biết vì sao bài của họ biến mất, và “có gì đó sai” chẳng nói cho họ điều gì họ chưa tự đoán ra. Một fetch thất bại sẽ đưa bài đó ra khỏi hàng chờ ở mọi nơi nó đang chờ.
Phản hồi cho bất kỳ yêu cầu nào trong số này là { "ok": true, "cancelled": false }. cancelled: true nghĩa là hãy dừng: job đã bị bỏ trong lúc bạn đang làm. Một job không phải của bạn, hoặc không có đó, là 404. Một state khác working, done hay failed là 400.
Chờ đợi, từ phía phòng
Một bài đã xếp mà tệp chưa tồn tại được giữ ở trạng thái đang chờ (pending). Nó nằm trong hàng chờ, nó hiện tiến độ của mình, và nó không bao giờ được trao cho màn hình dưới dạng một URL, nên một bài tải dở không bao giờ là một khung đen trước mặt cả phòng. Lần đồng bộ cuối cùng báo externalId của nó là thứ làm nó trở thành bình thường.
Theo mặc định một phòng phát bài sẵn sàng đầu tiên thay vì bài đầu tiên trong hàng chờ, để một lần tải không bao giờ làm cả phòng đứng chờ; người chủ trì có thể tắt điều đó và chờ theo đúng thứ tự. Cả hai đều không phải việc của bạn ngoài việc trả lời kịp thời, nhưng đó là lý do một lần tải chậm vẫn chịu được.
Nghe thử
Sáu bản karaoke của cùng một bài không phân biệt được qua tên, và một lần đoán sai tốn cả phòng ba phút. Nghe thử cho phép ai đó nghe một đoạn của một bản trước khi quyết định cho cả phòng.
Chọn tham gia bằng canPreview cùng với canSearchRemotely, rồi phát các byte nghe thử tại route media bạn đã có:
GET <baseUrl>/media/<externalId>?t=<mediaToken>&preview=1
Cùng token, cùng yêu cầu range và CORS, cùng 403 khi token sai. Thêm một nhánh nữa trong bộ xử lý bạn đã viết, thay vì một máy chủ thứ hai.
Bản nghe thử có thể là bản rẻ hơn bản thật. Độ phân giải thấp hơn, một đoạn ngắn hơn, bất cứ thứ gì nhanh: không ai hát theo nó. Chúng tôi không bao giờ phát nó lên màn hình. Nó chỉ đến điện thoại của một người, theo yêu cầu, và việc phát của chính phòng luôn chờ một lần tải thật.
Điều bạn làm với nó sau đó là việc của bạn. Nếu ai đó xếp một bài bạn đã cho nghe thử và bản nghe thử của bạn tình cờ đủ tốt để giữ, một lần tải sau đó cho nó có thể xong gần như tức thì. Đó là một tối ưu bên trong bộ nhớ đệm của bạn, không phải một quy tắc: một provider vứt bản nghe thử đi và tải lại cho đúng cũng đúng như vậy, và không gì ở đây cần biết bạn chọn cách nào.
Các bản nghe thử mang tính đầu cơ, vì chúng là media chưa ai cam kết sẽ hát, nên chúng xứng đáng có mức trần riêng trên đĩa của bạn và cách dọn dẹp riêng, tách khỏi thư viện mà một phòng đang thực sự dùng.
Nói rõ bạn chịu được những gì
Một lần tải tiêu tốn đĩa, băng thông và CPU của ai đó, và người đó là bạn. Hãy gửi limits cùng với capabilities trong bất kỳ lần đồng bộ nào, và chúng tôi sẽ thực thi chúng:
"limits": {
"pendingFetchesPerRoom": 5,
"pendingFetchesPerPerson": 2,
"pendingPreviewsPerRoom": 3,
"guestRequests": true,
"fetchTimeoutSeconds": 600,
"previewTimeoutSeconds": 120
}
Tất cả đều tùy chọn. guestRequests: false giới hạn việc hỏi chỉ cho chủ trì, đó là câu trả lời khi một laptop được cho mượn cho một phòng bốn mươi người. fetchTimeoutSeconds là lúc chúng tôi bỏ cuộc với bạn và báo cho người hát. Các lời từ chối nêu tên giới hạn, để người đụng phải nó biết nó là gì thay vì chỉ biết là họ không được.
Bản nghe thử có ngân sách riêng vì chúng rẻ để yêu cầu và dễ yêu cầu lặp đi lặp lại: một phòng người tò mò bấm qua các kết quả tìm kiếm không nên có thể tiêu hết một buổi tối băng thông của ai đó. Cũng hãy bỏ cuộc với một bản nghe thử sớm hơn một lần tải. Không ai chờ hai phút để biết một bài có đúng bản hay không.
Bất cứ thứ gì không gửi sẽ có giá trị mặc định. Không có mức trần cho số lần tải hay nghe thử đang chờ, khách được phép hỏi, một lần tải bị bỏ sau 600 giây, và một bản nghe thử sau 120 giây. Một số lượng hay số giây phải là số dương, và được làm tròn xuống; bất cứ giá trị nào khác được coi như chưa gửi. guestRequests chỉ bị tắt bởi một false nguyên văn.
Giới hạn là của bạn để đặt vì cái máy là của bạn; việc một phòng làm gì với một bài chậm là của người chủ trì, và điều đó không được thương lượng ở đây.
Một console của riêng bạn
Nếu bạn có một giao diện, để nạp sẵn trước buổi tiệc hay vì bất cứ việc gì khác, hãy báo nó là consoleUrl trong nội dung đồng bộ, theo cùng điều kiện như baseUrl: HTTPS, và một chứng chỉ mà trình duyệt tin cậy. Chủ thư viện, và không ai khác, được đưa một liên kết tới nó.
Hãy tự bảo vệ nó, và không dùng bất cứ thứ gì chúng tôi giữ. Chúng tôi chỉ hiển thị một địa chỉ; chúng tôi không muốn bí mật của bạn, và một liên kết mang theo bí mật là một liên kết bị rò rỉ.