Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with local Audio and Video #2380

Merged
merged 5 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions panel/pane/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class _MediaBase(PaneBase):

_rename = {'name': None, 'sample_rate': None, 'object': 'value'}

_rerender_params = []

_updates = True

__abstract = True
Expand All @@ -60,8 +62,6 @@ def applies(cls, obj):

def _get_model(self, doc, root=None, parent=None, comm=None):
props = self._process_param_change(self._init_params())
if self.object is not None:
props['value'] = self.object
model = self._bokeh_model(**props)
if root is None:
root = model
Expand All @@ -85,6 +85,7 @@ def _process_param_change(self, msg):
msg = super()._process_param_change(msg)
if 'value' in msg:
value = msg['value']
fmt = self._default_mime
if isinstance(value, np.ndarray):
fmt = 'wav'
buffer = self._from_numpy(value)
Expand All @@ -96,14 +97,11 @@ def _process_param_change(self, msg):
data = b64encode(data)
elif value.lower().startswith('http'):
return msg
elif not value:
data, fmt = b'', self._default_mime
elif not value or value == f'data:{self._media_type}/{fmt};base64,':
data = b''
else:
raise ValueError('Object should be either path to a sound file or numpy array')
template = 'data:audio/{mime};base64,{data}'
msg['value'] = template.format(data=data.decode('utf-8'),
mime=fmt)

raise ValueError(f'Object should be either path to a {self._media_type} file or numpy array.')
msg['value'] = f"data:{self._media_type}/{fmt};base64,{data.decode('utf-8')}"
return msg


Expand Down
Binary file added panel/tests/pane/assets/mp3.mp3
Binary file not shown.
Binary file added panel/tests/pane/assets/mp4.mp4
Binary file not shown.
44 changes: 43 additions & 1 deletion panel/tests/pane/test_media.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from panel.pane import Video
import pathlib

import numpy as np

from panel.pane import Audio, Video

ASSETS = pathlib.Path(__file__).parent / 'assets'


def test_video_url(document, comm):
Expand All @@ -8,3 +14,39 @@ def test_video_url(document, comm):

# To check if url is send to the bokeh model
assert model.value == url


def test_local_video(document, comm):
video = Video(str(ASSETS / 'mp4.mp4'))
model = video.get_root(document, comm=comm)

assert model.value == 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAAhtZGF0AAAA1m1vb3YAAABsbXZoZAAAAAAAAAAAAAAAAAAAA+gAAAAAAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAABidWR0YQAAAFptZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAAC1pbHN0AAAAJal0b28AAAAdZGF0YQAAAAEAAAAATGF2ZjU3LjQxLjEwMA==' # noqa


def test_local_audio(document, comm):
audio = Audio(str(ASSETS / 'mp3.mp3'))
model = audio.get_root(document, comm=comm)

assert model.value == 'data:audio/mp3;base64,/+MYxAAAAANIAAAAAExBTUUzLjk4LjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' # noqa


def test_numpy_audio(document, comm):
sps = 8000 # Samples per second
duration = 0.01 # Duration in seconds

modulator_frequency = 2.0
carrier_frequency = 120.0
modulation_index = 2.0

time = np.arange(sps*duration) / sps
modulator = np.sin(2.0 * np.pi * modulator_frequency * time) * modulation_index
waveform = np.sin(2. * np.pi * (carrier_frequency * time + modulator))

waveform_quiet = waveform * 0.3
waveform_int = np.int16(waveform_quiet * 32767)

audio = Audio(waveform_int, sample_rate=sps)

model = audio.get_root(document, comm=comm)

assert model.value == 'data:audio/wav;base64,UklGRsQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YaAAAAAAAF4ErQjgDOgQuBRDGH0bXB7WIOMifCScJT8mYyYHJi0l1yMLIs0fJR0dGr4WFBMqDw4LzQZ1Ahf+vfl59VfxZu2z6UrmN+OD4DjeXNz42g7aotm22UjaWNvi3ODeTOEe5E3nzuqU7pXywvYO+2v/yAMZCFAMXhA1FMoXDxv7HYMgoCJJJHolLyZlJhwmVSURJFciKiCTHZoaSBeqE8oP' # noqa
14 changes: 10 additions & 4 deletions panel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,16 @@ def param_reprs(parameterized, skip=None):
default = parameterized.param[p].default
equal = v is default
if not equal:
try:
equal = bool(v==default)
except Exception:
equal = False
if isinstance(v, np.ndarray):
if isinstance(default, np.ndarray):
equal = np.array_equal(v, default, equal_nan=True)
else:
equal = False
else:
try:
equal = bool(v==default)
except Exception:
equal = False

if equal: continue
elif v is None: continue
Expand Down