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 |
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 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ể 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 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 . 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="//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>
const streamUrl = '//[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();
ivsPlayer.addEventListener(IVSPlayer.PlayerState.PLAYING, (evt) => { window.time = Date.now(); });
ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { const now = Date.now(); console.log(`${(now - window.time) / 1000} seconds since last event`); window.time = now; });
window.ivsPlayer.addEventListener(IVSPlayer.MetadataEventType.ID3, (evt) => { console.log(evt); });
Đâ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)); });
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; }