Add audio files and audio embeds

This commit is contained in:
sarah committed 2026-10-14 19:40:33 +02:00
1 parent d86e33fd4a
commit 2d5ab15f52
10 files changed
+73 -7

No files matched your search

+14
View File
@@ -19,6 +19,7 @@ DescriptionExcerptLength = 200
DefaultDescriptions = {
"directory": "A directory on SaraView.",
"video": "A video on SaraView.",
"audio": "Audio on SaraView.",
"image": "An image on SaraView.",
"note": "A note on SaraView.",
"file": "A file on SaraView.",
@@ -89,6 +90,19 @@ def BuildOgTags(RootName: str, RelativePath: str, IsDirectoryUrl: bool, BaseUrl:
Tags.append(_MetaTag("og:video:secure_url", MediaUrl))
Tags.append(_MetaTag("og:video:type", GetMimeType(EntryPath)))
Tags.append(_MetaTag("og:description", DefaultDescriptions["video"]))
elif FileType == "audio":
# og:audio is the standard tag, but Discord doesn't play it. Discord
# does play og:video in an HTML5 player, which handles audio-only
# files too, so the audio is offered as both.
Tags.append(_MetaTag("og:type", "video.other"))
Tags.append(_MetaTag("og:audio", MediaUrl))
Tags.append(_MetaTag("og:audio:secure_url", MediaUrl))
Tags.append(_MetaTag("og:audio:type", GetMimeType(EntryPath)))
Tags.append(_MetaTag("og:video", MediaUrl))
Tags.append(_MetaTag("og:video:url", MediaUrl))
Tags.append(_MetaTag("og:video:secure_url", MediaUrl))
Tags.append(_MetaTag("og:video:type", GetMimeType(EntryPath)))
Tags.append(_MetaTag("og:description", DefaultDescriptions["audio"]))
elif FileType == "image":
Tags.append(_MetaTag("og:type", "website"))
Tags.append(_MetaTag("og:image", MediaUrl))
+4
View File
@@ -34,6 +34,10 @@ FileTypeMap = {
".webm": "video",
".mov": "video",
".mkv": "video",
".flac": "audio",
".ogg": "audio",
".mp3": "audio",
".wav": "audio",
}
+4
View File
@@ -18,6 +18,10 @@ MimeTypeMap = {
".webm": "video/webm",
".mov": "video/quicktime",
".mkv": "video/x-matroska",
".flac": "audio/flac",
".ogg": "audio/ogg",
".mp3": "audio/mpeg",
".wav": "audio/wav",
}
+2 -1
View File
@@ -18,7 +18,8 @@ from Viewer import FileView
DoubleClickWindow = 0.4 # seconds
TypeLabels = {"markdown": "Markdown", "text": "Text", "config": "Config", "html": "HTML", "image": "Image", "video": "Video"}
TypeLabels = {"markdown": "Markdown", "text": "Text", "config": "Config", "html": "HTML", "image": "Image", "video": "Video",
"audio": "Audio"}
class Browser(ft.Column):
+1
View File
@@ -85,6 +85,7 @@ FileIcons = {
"html": ft.Icons.CODE,
"image": ft.Icons.IMAGE_OUTLINED,
"video": ft.Icons.MOVIE_OUTLINED,
"audio": ft.Icons.MUSIC_NOTE_OUTLINED,
}
_ThemeRoleMap = {
+1
View File
@@ -27,6 +27,7 @@ FileTypeMap = {
".html": "html", ".htm": "html",
".png": "image", ".jpg": "image", ".jpeg": "image", ".gif": "image", ".webp": "image", ".svg": "image",
".mp4": "video", ".webm": "video", ".mov": "video", ".mkv": "video",
".flac": "audio", ".ogg": "audio", ".mp3": "audio", ".wav": "audio",
}
TextFileTypes = {"markdown", "text", "config", "html"}
+4 -3
View File
@@ -193,9 +193,10 @@ class FileView(ft.Container):
return ft.Column(Views or [View], scroll=ft.ScrollMode.AUTO, expand=True)
def _InfoView(self) -> ft.Control:
Icon = ft.Icons.MOVIE_OUTLINED if self.FileType == "video" else ft.Icons.INSERT_DRIVE_FILE_OUTLINED
Note = ("Videos play in your system's video player: use Open Externally."
if self.FileType == "video" else "SaraView can't show this type of file. Use Open Externally.")
Icon, Note = {
"video": (ft.Icons.MOVIE_OUTLINED, "Videos play in your system's video player: use Open Externally."),
"audio": (ft.Icons.MUSIC_NOTE_OUTLINED, "Audio plays in your system's music player: use Open Externally."),
}.get(self.FileType, (ft.Icons.INSERT_DRIVE_FILE_OUTLINED, "SaraView can't show this type of file. Use Open Externally."))
return ft.Column(
[
ft.Icon(Icon, size=64, color=Palette.Mauve),
+20
View File
@@ -88,6 +88,10 @@ const LinkedFileTypeMap = {
".webm": "video",
".mov": "video",
".mkv": "video",
".flac": "audio",
".ogg": "audio",
".mp3": "audio",
".wav": "audio",
};
function ClassifyLinkedFile(LinkedPath) {
@@ -370,6 +374,22 @@ export default function PreviewPane({
);
}
if (FileType === "audio") {
return (
<div className="PreviewMedia">
<div className={ToolbarClass}>
<a className="DownloadButton" href={GetDownloadUrl(RootName, FilePath)}>
Download
</a>
</div>
<div className="PreviewAudio">
<div className="PreviewAudioName">{FilePath.split("/").pop()}</div>
<audio controls src={GetFileUrl(RootName, FilePath)} />
</div>
</div>
);
}
if (FileType === "html" && !IsEditing) {
return (
<div className="PreviewFrame">
+19
View File
@@ -968,6 +968,25 @@ img,
max-height: 100%;
}
.PreviewAudio {
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 24px;
}
.PreviewAudioName {
color: var(--Purple);
}
.PreviewAudio audio {
width: min(480px, 90vw);
accent-color: var(--Purple);
color-scheme: dark; /* the browser's dark controls, not a white bar */
}
.PreviewFrame iframe {
flex: 1;
border: none;
+4 -3
View File
@@ -1,7 +1,7 @@
# SaraView
A self-hosted web file previewer/editor. Obsidian's look, without the parts
you don't use, plus image and video previewing. Read-only integration with
you don't use, plus image, video and audio previewing. Read-only integration with
SaraTag's per-file Book tags is included.
It's made by Sarah, hence the name. :3
@@ -19,7 +19,8 @@ Example use-cases:
- Browsing and editing markdown notes from your phone, without installing
anything.
- Previewing images and videos that live next to your notes.
- Previewing images, videos and audio (FLAC, OGG, MP3, WAV) that live next to your notes.
Links to them embed in Discord and other apps that read Open Graph tags.
- Giving a friend or family member their own login, with a directory only
they can see.
@@ -294,7 +295,7 @@ the web view's settings): **Live** shows it rendered and lets you edit
in place, like Obsidian (click a heading to see and edit its `#`s; Esc puts
it back), with Source (Ctrl+E) for the plain text; **Separate** keeps View
and Edit as two modes. Images show in the app;
videos and other files open in their default program (Open Externally).
videos, audio and other files open in their default program (Open Externally).
**Graph** (the toolbar's graph button or Ctrl+G here, the Graph button at
the top of the web view's sidebar) shows everything under a root, or under