Skip to content

Commit

Permalink
improvement: large audio files (#1090)
Browse files Browse the repository at this point in the history
Use virtual files in `mo.audio()` to make it possible to include
large audio files. Gets around marimo's limitation on the amount of data
the kernel can pass to the server.

Additionally, make it possible to use a path to local file in
mo.audio().
  • Loading branch information
akshayka authored Apr 8, 2024
1 parent ecf43e4 commit 005052f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
16 changes: 16 additions & 0 deletions marimo/_output/data/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ def image(data: bytes, ext: str = "png") -> VirtualFile:
return item.virtual_file


def audio(data: bytes, ext: str = "wav") -> VirtualFile:
"""Create a virtual file from audio.
**Args.**
- data: Audio data in bytes
**Returns.**
A `VirtualFile` object.
"""
item = VirtualFileLifecycleItem(ext=ext, buffer=data)
get_context().cell_lifecycle_registry.add(item)
return item.virtual_file


def csv(
data: Union[str, bytes, io.BytesIO, "pd.DataFrame", "pl.DataFrame"]
) -> VirtualFile:
Expand Down
32 changes: 25 additions & 7 deletions marimo/_plugins/stateless/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from __future__ import annotations

import io
from typing import Union
import os
from typing import Optional, Union

import marimo._output.data.data as mo_data
from marimo._output.builder import h
from marimo._output.hypertext import Html
from marimo._output.rich_help import mddoc
Expand All @@ -23,18 +25,34 @@ def audio(
src="https://upload.wikimedia.org/wikipedia/commons/8/8c/Ivan_Ili%C4%87-Chopin_-_Prelude_no._1_in_C_major.ogg"
)
with open("recording.wav", "rb") as file:
mo.audio(src=file)
mo.audio(src="path/to/local/file.wav")
```
**Args.**
- `src`: the URL of the audio or a file-like object
- `src`: a path or URL to an audio file, bytes,
or a file-like object opened in binary mode
**Returns.**
An audio player as an `Html` object.
"""
resolved_src = io_to_data_url(src, fallback_mime_type="audio/wav")
audio = h.audio(src=resolved_src, controls=True)
return Html(audio)
resolved_src: Optional[str]

if isinstance(src, (io.BufferedReader, io.BytesIO)):
pos = src.tell()
src.seek(0)
resolved_src = mo_data.audio(src.read()).url
src.seek(pos)
elif isinstance(src, bytes):
resolved_src = mo_data.audio(src).url
elif isinstance(src, str) and os.path.isfile(os.path.expanduser(src)):
src = os.path.expanduser(src)
with open(src, "rb") as f:
resolved_src = mo_data.audio(
f.read(), ext=os.path.splitext(src)[1]
).url
else:
resolved_src = io_to_data_url(src, fallback_mime_type="audio/wav")

return Html(h.audio(src=resolved_src, controls=True))

0 comments on commit 005052f

Please sign in to comment.