From 24a8cbcab4451b9f34a0ce7fbd59e4769ad5a392 Mon Sep 17 00:00:00 2001 From: nklhrstv Date: Fri, 10 Jun 2022 18:30:47 +0300 Subject: [PATCH] fix chromecast transport for large messages --- package-lock.json | 18 ++++---- package.json | 2 +- src/routes/Player/Video/Video.js | 2 +- src/services/Chromecast/Chromecast.js | 4 +- .../Chromecast/ChromecastTransport.js | 42 +++++++++++++++++-- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index f47262bca..91939b9b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1856,9 +1856,9 @@ "integrity": "sha512-knlcBibqJW2mbEgid6YEeQN9FPkIGAEtozYWqzKWeHd2DPY2nl8kYX2pMQpa2Db/RVSqbVstu/gdey5TtSgGYw==" }, "@stremio/stremio-video": { - "version": "0.0.19-rc.1", - "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.19-rc.1.tgz", - "integrity": "sha512-UiML0reTHcBhb2cddTrw7BqwYnJ7FcjOANltszmcG9Rx6PiJbZdfwZ2CR3VQX91nXbQlpeq81SjPt4WwcdXmuQ==", + "version": "0.0.20-rc.4", + "resolved": "https://registry.npmjs.org/@stremio/stremio-video/-/stremio-video-0.0.20-rc.4.tgz", + "integrity": "sha512-hRVXSH/3MsdQ2GNE56FqaUDT39PELoHV1BGRO9gLPIAJSX+nMlTs1eupGuGVcBdCnqPwEfZyRgpG0lRAmjLrRw==", "requires": { "color": "4.2.3", "deep-freeze": "0.0.1", @@ -3725,7 +3725,7 @@ "deep-freeze": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", - "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=" + "integrity": "sha512-Z+z8HiAvsGwmjqlphnHW5oz6yWlOwu6EQfFTjmeTWlDeda3FS2yv3jhq35TX/ewmsnqB+RX2IdsIOyjJCQN5tg==" }, "deep-is": { "version": "0.1.4", @@ -4992,7 +4992,7 @@ "hat": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", - "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=" + "integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==" }, "he": { "version": "1.2.0", @@ -8413,7 +8413,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" }, "qs": { "version": "6.9.6", @@ -8424,7 +8424,7 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" }, "queue-microtask": { "version": "1.2.3", @@ -8973,7 +8973,7 @@ "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" }, @@ -9438,7 +9438,7 @@ "thirty-two": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-1.0.2.tgz", - "integrity": "sha1-TKL//AKlEpDSdEueP1V2k8prYno=" + "integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==" }, "throat": { "version": "6.0.1", diff --git a/package.json b/package.json index 7dc6a3bbc..a8b746418 100755 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@stremio/stremio-colors": "4.0.1", "@stremio/stremio-core-web": "0.42.0", "@stremio/stremio-icons": "3.0.5", - "@stremio/stremio-video": "0.0.19-rc.1", + "@stremio/stremio-video": "0.0.20-rc.4", "a-color-picker": "1.2.1", "buffer": "6.0.3", "classnames": "2.3.1", diff --git a/src/routes/Player/Video/Video.js b/src/routes/Player/Video/Video.js index e3b7fd481..8446457b5 100644 --- a/src/routes/Player/Video/Video.js +++ b/src/routes/Player/Video/Video.js @@ -70,7 +70,7 @@ const Video = React.forwardRef(({ className, ...props }, ref) => { }); } return () => { - dispatch({ type: 'command', commandName: 'destroy' }); + videoRef.current.destroy(); }; }, []); return ( diff --git a/src/services/Chromecast/Chromecast.js b/src/services/Chromecast/Chromecast.js index 7d7c4b828..c025f2dee 100644 --- a/src/services/Chromecast/Chromecast.js +++ b/src/services/Chromecast/Chromecast.js @@ -17,7 +17,7 @@ function Chromecast() { starting = false; onStateChanged(); } - function onTransportError(args) { + function onTransportInitError(args) { console.error(args); active = false; error = new Error('Google Cast API not available'); @@ -68,7 +68,7 @@ function Chromecast() { starting = true; transport = new ChromecastTransport(); transport.on('init', onTransportInit); - transport.on('error', onTransportError); + transport.on('init-error', onTransportInitError); onStateChanged(); }; this.stop = function() { diff --git a/src/services/Chromecast/ChromecastTransport.js b/src/services/Chromecast/ChromecastTransport.js index 8cd84eeba..7c82f80ae 100644 --- a/src/services/Chromecast/ChromecastTransport.js +++ b/src/services/Chromecast/ChromecastTransport.js @@ -3,6 +3,7 @@ const EventEmitter = require('eventemitter3'); const MESSAGE_NAMESPACE = 'urn:x-cast:com.stremio'; +const CHUNK_SIZE = 20000; let castAPIAvailable = null; const castAPIEvents = new EventEmitter(); @@ -32,6 +33,7 @@ const initialize = () => { function ChromecastTransport() { const events = new EventEmitter(); + const chunks = []; initialize() .then(() => { @@ -52,11 +54,31 @@ function ChromecastTransport() { } }) .catch((error) => { - events.emit('error', error); + events.emit('init-error', error); }); function onMessage(_, message) { - events.emit('message', JSON.parse(message)); + try { + const { chunk, last } = JSON.parse(message); + chunks.push(chunk); + if (!last) { + return; + } + } catch (error) { + chunks.splice(0, chunks.length); + events.emit('message-error', error); + return; + } + + let parsedMessage; + try { + parsedMessage = JSON.parse(chunks.splice(0, chunks.length).join('')); + } catch (error) { + events.emit('message-error', error); + return; + } + + events.emit('message', parsedMessage); } function onApplicationStatusChanged(event) { events.emit(cast.framework.CastSession.APPLICATION_STATUS_CHANGED, event); @@ -135,7 +157,21 @@ function ChromecastTransport() { this.sendMessage = function(message) { const castSession = cast.framework.CastContext.getInstance().getCurrentSession(); if (castSession !== null) { - return castSession.sendMessage(MESSAGE_NAMESPACE, message); + const serializedMessage = JSON.stringify(message); + const chunksCount = Math.ceil(serializedMessage.length / CHUNK_SIZE); + const chunks = []; + for (let i = 0; i < chunksCount; i++) { + const start = i * CHUNK_SIZE; + const chunk = serializedMessage.slice(start, start + CHUNK_SIZE); + chunks.push(chunk); + } + + return Promise.all(chunks.map((chunk, index) => { + return castSession.sendMessage(MESSAGE_NAMESPACE, { + chunk, + last: index === chunks.length - 1, + }); + })); } else { return Promise.reject(new Error('Session not started')); }