2 Lưu trữ tin nhắn trò chuyện trên web với Amazon IVS Chat Logging |
3 Phát lại luồng trực tiếp Amazon IVS với Phát lại trò chuyện |
Trong một số bài đăng gần đây nhất, chúng tôi đã xem xét cách tự động ghi lại các luồng trực tiếp của Dịch vụ video tương tác Amazon (Amazon IVS) tới Amazon S3 và cách ghi nhật ký các tin nhắn được gửi tới phòng trò chuyện Amazon IVS (xem các liên kết ở trên). Trong bài đăng này, chúng tôi sẽ kết hợp hai khái niệm này lại với nhau để hoàn thiện trải nghiệm người dùng và tạo phát lại theo yêu cầu các luồng trực tiếp trước đây với phát lại toàn bộ cuộc trò chuyện.
Như đã thấy trong bài đăng trước của chúng tôi, các tin nhắn trò chuyện được ghi vào đích ghi nhật ký bao gồm dấu thời gian dựa trên GMT thể hiện ngày và giờ mà sự kiện được đăng bởi phòng trò chuyện Amazon IVS. Để thực hiện phát lại theo yêu cầu thực sự của một luồng trực tiếp hoàn chỉnh với phát lại tin nhắn trò chuyện tương tác vào thời điểm gần nhất có thể, chúng tôi cần lấy một luồng dấu thời gian dựa trên GMT thông thường từ luồng đã ghi mà chúng tôi có thể sử dụng để xác định những gì tin nhắn trò chuyện sẽ hiển thị tại bất kỳ thời điểm cụ thể nào trong quá trình phát lại luồng. Hiện tại không có nguồn tài liệu nào cung cấp thông tin này, nhưng hãy tìm hiểu SDK trình phát Amazon IVS và xem liệu chúng tôi có thể tìm thấy thứ gì đó sẽ giúp chúng tôi thực hiện nhiệm vụ này không.
Khi cố gắng giải quyết vấn đề này, suy nghĩ đầu tiên của tôi là xem xét siêu dữ liệu được liên kết với luồng trực tiếp để xem liệu có bất kỳ thông tin có giá trị nào ẩn trong đó hay không. Rất may, dường như có một giá trị trong luồng siêu dữ liệu thông thường có thể được sử dụng cho mục đích phát lại cuộc trò chuyện của chúng tôi. Trong thử nghiệm của tôi, mỗi luồng chứa siêu dữ liệu ID3 dường như được đưa vào bởi quy trình chuyển mã Amazon IVS. Các thẻ ID3 này chứa dấu thời gian hữu ích mà chúng tôi có thể sử dụng để hỗ trợ phát lại cuộc trò chuyện. Để lắng nghe những sự kiện này, chúng ta có thể đính kèm một trình xử lý lắng nghe loại sự kiện IVSPlayer.MetadataEventType.ID3
. Loại sự kiện này được ghi lại, nhưng các tài liệu không nói nhiều về nó hoặc đưa ra bất kỳ đảm bảo nào về những gì nó có thể chứa.
Bạn muốn tránh các tính năng không có giấy tờ ? Nếu lo ngại về việc sử dụng tính năng không có giấy tờ, bạn có thể đưa siêu dữ liệu được hẹn giờ của riêng mình vào luồng trực tiếp với dấu thời gian thích hợp khi tin nhắn mới được đăng vào phòng trò chuyện Amazon IVS của bạn. Hãy nhớ rằng có các giới hạn về kích thước và tần suất đăng các sự kiện
PutMetadata
qua API.
Hãy thiết lập trình phát Amazon IVS để phát lại luồng đã ghi bằng SDK trình phát. Trước tiên, chúng tôi sẽ bao gồm SDK trình phát Amazon IVS mới nhất thông qua thẻ <script>
.
Bạn mới sử dụng Amazon IVS? Xem loạt blog Bắt đầu với Amazon Interactive Video Service . Nếu bạn có câu hỏi về cách bắt đầu, hãy đăng nhận xét về bất kỳ bài đăng nào trong loạt bài đó (hoặc bên dưới)!
<script src="https://player.live-video.net/1.16.0/amazon-ivs-player.min.js"></script>
Như thường lệ, chúng ta sẽ cần đưa phần tử <video>
vào phần đánh dấu HTML sẽ được sử dụng để phát lại.
<video id="video-player" muted controls autoplay playsinline></video>
Bây giờ chúng ta có thể tạo một phiên bản của trình phát IVS. Tôi đang mã hóa URL bên dưới, nhưng bạn có thể lấy URL này thông qua phương pháp được mô tả trong bài đăng này [việc cần làm: liên kết].
const streamUrl = 'https://[redacted].cloudfront.net/ivs/v1/[redacted]/[redacted]/2022/11/17/18/6/[redacted]/media/hls/master.m3u8'; const videoEl = document.getElementById('video-player'); const ivsPlayer = IVSPlayer.create(); ivsPlayer.attachHTMLVideoElement(videoEl); ivsPlayer.load(streamUrl); ivsPlayer.play();
Như đã đề cập ở trên, để hữu ích cho mục đích này, chúng tôi cần một luồng dấu thời gian thông thường. Để biết tần suất siêu dữ liệu ID3 được nhận, hãy cộng thêm thời gian. Trước tiên, hãy ghi lại dấu thời gian ngay khi luồng bắt đầu phát.
ivsPlayer.addEventListener(IVSPlayer.PlayerState.PLAYING, (evt) => { window.time = Date.now(); });
Tiếp theo, chúng tôi sẽ thêm trình xử lý sự kiện ID3, ghi nhật ký thời gian và đặt lại bộ hẹn giờ.
ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { const now = Date.now(); console.log(`${(now - window.time) / 1000} seconds since last event`); window.time = now; });
Bây giờ chúng ta có thể bắt đầu phát lại và quan sát bảng điều khiển để xem tần suất các sự kiện được kích hoạt.
Trong thử nghiệm của tôi, các sự kiện được kích hoạt cứ sau 1-2 giây. Nó không phải là thời gian thực, nhưng nó có thể đủ tốt cho hầu hết các tình huống. Bây giờ chúng ta hãy xem sự kiện để xem nó chứa dữ liệu gì.
window.ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { console.log(evt); });
Khi chúng tôi bắt đầu phát lại với trình nghe ở trên được đính kèm, chúng tôi có thể thấy thông tin sau được ghi vào bảng điều khiển trình duyệt.
Đây là thông tin rất thú vị, nhưng hơi khó hiểu. Dựa trên thử nghiệm của tôi, transc_s
dường như là dấu thời gian mà chúng tôi đang theo dõi. Hãy sửa đổi trình xử lý sự kiện để lấy dấu thời gian đó và ghi nhật ký.
window.ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { const segmentMetadata = evt.find((tag) => tag.desc === 'segmentmetadata'); const segmentMetadataInfo = JSON.parse(segmentMetadata.info[0]); const timestamp = segmentMetadataInfo['transc_s']; const timestampWithMs = timestamp * 1000; console.log(timestampWithMs); console.log(new Date(timestamp)); });
Điều này tạo ra đầu ra sau cho bài kiểm tra của tôi.
Nếu tôi tìm kiếm một thời điểm ngẫu nhiên trong video, dấu thời gian thích hợp luôn chính xác. Điều này có nghĩa là cứ sau 1-2 giây, chúng tôi biết dấu thời gian GMT hợp lệ của thời điểm mà sự kiện được ghi lại trong luồng. Điều này có nghĩa là chúng ta có thể giả định rằng tất cả tin nhắn trò chuyện được gửi trước dấu thời gian này đã được đăng lên cuộc trò chuyện và sẽ hiển thị trong vùng chứa trò chuyện.
Khi trang của tôi tải, tôi có thể sử dụng phương pháp được nêu trong bài viết trước [việc cần làm: liên kết] trong loạt bài này để truy xuất toàn bộ nhật ký trò chuyện cho luồng và hiển thị nhật ký đó trong vùng chứa trò chuyện <div>
. Vì không có thông báo nào được hiển thị khi bắt đầu luồng, nên tôi sẽ đảm bảo rằng cuộc gọi đó chứa một lớp ẩn chúng khỏi người dùng và lưu trữ thuộc tính dữ liệu với dấu thời gian phù hợp để tôi có thể biết thông báo nào sẽ hiển thị đưa ra bất kỳ dấu thời gian nào trong luồng.
window.chatLog = await getChatLogs(logGroupName, chatArn, startTime, endTime); renderChat();
Hàm renderChat()
của tôi xử lý việc đăng từng tin nhắn lên vùng chứa trò chuyện.
const renderChat = () => { const chatContainer = document.getElementById('chat'); window.chatLog.forEach(msg => { const msgTemplate = document.getElementById('chatMsgTemplate'); const msgEl = msgTemplate.content.cloneNode(true); const ts = new Date(msg.event_timestamp).getTime() * 1000; msgEl.querySelector('.msg-container').setAttribute('data-timestamp', ts); msgEl.querySelector('.chat-username').innerHTML = msg.payload.Attributes.username; msgEl.querySelector('.msg').innerHTML = msg.payload.Content; chatContainer.appendChild(msgEl); }); };
Bây giờ tôi có thể sửa đổi trình nghe ID3 để gọi hàm replayChat()
và chuyển dấu thời gian hiện tại cho nó.
window.ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { const segmentMetadata = evt.find((tag) => tag.desc === 'segmentmetadata'); const segmentMetadataInfo = JSON.parse(segmentMetadata.info[0]); const timestamp = segmentMetadataInfo['transc_s']; const timestampWithMs = timestamp * 1000; replayChat(timestampWithMs); });
Trong replayChat()
, tôi có thể tìm thấy tất cả nút trò chuyện chứa dấu thời gian nhỏ hơn hoặc bằng dấu thời gian hiện tại từ luồng đã ghi và hiển thị/ẩn bất kỳ tin nhắn trò chuyện nào dựa trên dấu thời gian đó.
const replayChat = (currentTimestamp) => { Array.from(document.querySelectorAll('[data-timestamp]')).forEach(node => { const chatMsgTs = Number(node.getAttribute('data-timestamp')); const isVisible = chatMsgTs <= currentTimestamp; if (isVisible) { node.classList.remove('d-none'); } else { node.classList.add('d-none'); } }); const chatContainer = document.getElementById('chat'); chatContainer.scrollTop = chatContainer.scrollHeight; }
Tại thời điểm này, chúng tôi đã đạt được mục tiêu phát lại luồng trực tiếp Amazon IVS đã ghi với bản phát lại toàn bộ cuộc trò chuyện.
Trong bài đăng này, chúng tôi đã xem xét cách kết hợp các luồng trực tiếp Amazon IVS đã ghi với các tin nhắn trò chuyện đã ghi để tạo phát lại luồng theo yêu cầu với các tin nhắn trò chuyện được định thời gian phù hợp.