diff --git a/js/lib/widget.js b/js/lib/widget.js index d69bbe4..de09eff 100644 --- a/js/lib/widget.js +++ b/js/lib/widget.js @@ -90,8 +90,7 @@ export class RemoteFrameBufferModel extends DOMWidgetModel { */ on_msg(msg, buffers) { if (msg.type === 'framebufferdata') { - let blob = new Blob([buffers[0].buffer], { type: msg.mimetype }); - this.frames.push({ ...msg, blob: blob }); + this.frames.push({ ...msg, buffers: buffers }); } } @@ -142,12 +141,18 @@ export class RemoteFrameBufferModel extends DOMWidgetModel { } // Pick the oldest frame from the stack let frame = this.frames.shift(); - let new_url = URL.createObjectURL(frame.blob); - let old_url = this.img_elements?.[0]?.src; - URL.revokeObjectURL(old_url); + let new_src; + if (frame.buffers.length > 0) { + let blob = new Blob([frame.buffers[0].buffer], { type: frame.mimetype }); + new_src = URL.createObjectURL(blob); + } else { + new_src = frame.data_b64; + } + let old_src = this.img_elements?.[0]?.src; + if (old_src.startsWith('blob:')) { URL.revokeObjectURL(old_src); } // Update the image sources for (let img of this.img_elements) { - img.src = new_url; + img.src = new_src; } // Let the server know we processed the image (even if it's not shown yet) this.last_frame = frame; diff --git a/jupyter_rfb/widget.py b/jupyter_rfb/widget.py index 817ad8c..d8e3350 100644 --- a/jupyter_rfb/widget.py +++ b/jupyter_rfb/widget.py @@ -14,6 +14,7 @@ import asyncio import time +from base64 import encodebytes import ipywidgets import numpy as np @@ -90,6 +91,7 @@ def __init__(self, *args, **kwargs): self._rfb_last_resize_event = None self._rfb_warned_png = False self._rfb_lossless_draw_info = None + self._use_websocket = False # Could be a prop, private for now # Init stats self.reset_stats() # Setup events @@ -285,6 +287,12 @@ def _rfb_send_frame(self, array, is_lossless_redraw=False): # Turn array into a based64-encoded JPEG or PNG t1 = time.perf_counter() mimetype, data = array2compressed(array, quality) + if self._use_websocket: + datas = [data] + data_b64 = None + else: + datas = [] + data_b64 = f"data:{mimetype};base64," + encodebytes(data).decode() t2 = time.perf_counter() if "jpeg" in mimetype: @@ -314,10 +322,11 @@ def _rfb_send_frame(self, array, is_lossless_redraw=False): msg = dict( type="framebufferdata", mimetype=mimetype, + data_b64=data_b64, index=self._rfb_frame_index, timestamp=timestamp, ) - self.send(msg, [data]) + self.send(msg, datas) # ----- related to stats