@file-viewer/renderer-media 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/audio.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { FileViewerRenderedInstance } from '@file-viewer/core';
1
+ import { type FileRenderContext, type FileViewerRenderedInstance } from '@file-viewer/core';
2
2
  /**
3
3
  * Pure TypeScript audio renderer.
4
4
  *
5
5
  * Regular audio files use the browser's native `<audio>` element. MIDI stays in
6
6
  * the same async chunk and lazily imports `@tonejs/midi` only for `.mid/.midi`.
7
7
  */
8
- export default function renderAudio(buffer: ArrayBuffer, target: HTMLDivElement, type?: string): Promise<FileViewerRenderedInstance>;
8
+ export default function renderAudio(buffer: ArrayBuffer, target: HTMLDivElement, type?: string, context?: FileRenderContext): Promise<FileViewerRenderedInstance>;
package/dist/audio.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createFileViewerTranslator } from '@file-viewer/core';
1
2
  const AUDIO_MIME_MAP = {
2
3
  aac: 'audio/aac',
3
4
  flac: 'audio/flac',
@@ -74,7 +75,8 @@ const createRenderedInstance = (target, cleanup) => ({
74
75
  clearTarget(target);
75
76
  }
76
77
  });
77
- const renderAudioElement = (buffer, target, type) => {
78
+ const renderAudioElement = (buffer, target, type, context) => {
79
+ const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
78
80
  const normalizedType = type.trim().toLowerCase() || 'mp3';
79
81
  const mimeType = AUDIO_MIME_MAP[normalizedType] || 'audio/*';
80
82
  const sourceUrl = URL.createObjectURL(new Blob([buffer], { type: mimeType }));
@@ -83,7 +85,7 @@ const renderAudioElement = (buffer, target, type) => {
83
85
  const art = createElement('div', 'fv-audio-art');
84
86
  art.append(createElement('span'), createElement('i'));
85
87
  const copy = createElement('div', 'fv-audio-copy');
86
- copy.append(createElement('span', 'fv-audio-kicker', normalizedType.toUpperCase() || 'AUDIO'), createElement('strong', '', '音频预览'), createElement('p', '', '使用浏览器原生播放器打开,兼容性取决于当前浏览器支持的音频编码。'));
88
+ copy.append(createElement('span', 'fv-audio-kicker', normalizedType.toUpperCase() || 'AUDIO'), createElement('strong', '', t('media.audio.title')), createElement('p', '', t('media.audio.description')));
87
89
  const currentTimeText = createElement('span', '', '00:00');
88
90
  const durationText = createElement('span', '', '--:--');
89
91
  const progressFill = createElement('i');
@@ -96,7 +98,7 @@ const renderAudioElement = (buffer, target, type) => {
96
98
  audio.src = sourceUrl;
97
99
  audio.controls = true;
98
100
  audio.preload = 'metadata';
99
- audio.textContent = '当前浏览器不支持音频播放。';
101
+ audio.textContent = t('media.audio.unsupported');
100
102
  const handleLoadedMetadata = () => {
101
103
  durationText.textContent = Number.isFinite(audio.duration) && audio.duration > 0
102
104
  ? formatDuration(audio.duration)
@@ -121,14 +123,15 @@ const renderAudioElement = (buffer, target, type) => {
121
123
  URL.revokeObjectURL(sourceUrl);
122
124
  });
123
125
  };
124
- const renderMidiElement = (buffer, target) => {
126
+ const renderMidiElement = (buffer, target, context) => {
127
+ const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
125
128
  let disposed = false;
126
129
  const root = createElement('div', 'fv-midi-viewer');
127
130
  const card = createElement('section', 'fv-midi-card');
128
131
  const header = document.createElement('header');
129
- const title = createElement('strong', '', 'MIDI 文件');
132
+ const title = createElement('strong', '', t('media.midi.title'));
130
133
  header.append(createElement('span', '', 'MIDI'), title);
131
- const body = createElement('div', 'fv-midi-state', '正在解析 MIDI 轨道...');
134
+ const body = createElement('div', 'fv-midi-state', t('media.midi.loading'));
132
135
  card.append(header, body);
133
136
  root.append(card);
134
137
  target.replaceChildren(createStyle(), root);
@@ -141,7 +144,13 @@ const renderMidiElement = (buffer, target) => {
141
144
  const table = createElement('table', 'fv-midi-table');
142
145
  const thead = document.createElement('thead');
143
146
  const headerRow = document.createElement('tr');
144
- for (const label of ['轨道', '乐器', '通道', '音符数', '时长']) {
147
+ for (const label of [
148
+ t('media.midi.trackHeader'),
149
+ t('media.midi.instrumentHeader'),
150
+ t('media.midi.channelHeader'),
151
+ t('media.midi.noteCountHeader'),
152
+ t('media.midi.durationHeader')
153
+ ]) {
145
154
  headerRow.append(createElement('th', '', label));
146
155
  }
147
156
  thead.append(headerRow);
@@ -160,10 +169,10 @@ const renderMidiElement = (buffer, target) => {
160
169
  const totalNotes = input.tracks.reduce((sum, track) => sum + track.notes, 0);
161
170
  const stats = createElement('div', 'fv-midi-stats');
162
171
  for (const [label, value] of [
163
- ['时长', formatDuration(input.duration)],
172
+ [t('media.midi.durationStat'), formatDuration(input.duration)],
164
173
  ['PPQ', String(input.ppq)],
165
- ['轨道', String(input.tracks.length)],
166
- ['音符', String(totalNotes)]
174
+ [t('media.midi.trackStat'), String(input.tracks.length)],
175
+ [t('media.midi.noteStat'), String(totalNotes)]
167
176
  ]) {
168
177
  const stat = document.createElement('div');
169
178
  stat.append(createElement('span', '', label), createElement('strong', '', value));
@@ -179,7 +188,7 @@ const renderMidiElement = (buffer, target) => {
179
188
  return;
180
189
  }
181
190
  renderSummary({
182
- name: midi.name || 'MIDI 文件',
191
+ name: midi.name || t('media.midi.title'),
183
192
  duration: midi.duration,
184
193
  ppq: midi.header.ppq,
185
194
  tracks: midi.tracks.map((track, index) => {
@@ -196,7 +205,7 @@ const renderMidiElement = (buffer, target) => {
196
205
  }
197
206
  catch (error) {
198
207
  if (!disposed) {
199
- renderError(error instanceof Error ? error.message : 'MIDI 解析失败');
208
+ renderError(error instanceof Error ? error.message : t('media.midi.parseFailed'));
200
209
  }
201
210
  }
202
211
  })();
@@ -210,10 +219,10 @@ const renderMidiElement = (buffer, target) => {
210
219
  * Regular audio files use the browser's native `<audio>` element. MIDI stays in
211
220
  * the same async chunk and lazily imports `@tonejs/midi` only for `.mid/.midi`.
212
221
  */
213
- export default async function renderAudio(buffer, target, type) {
222
+ export default async function renderAudio(buffer, target, type, context) {
214
223
  const normalizedType = (type || 'mp3').toLowerCase();
215
224
  if (normalizedType === 'midi' || normalizedType === 'mid') {
216
- return renderMidiElement(buffer, target);
225
+ return renderMidiElement(buffer, target, context);
217
226
  }
218
- return renderAudioElement(buffer, target, normalizedType);
227
+ return renderAudioElement(buffer, target, normalizedType, context);
219
228
  }
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ if (mediaDefinitions.length !== mediaRendererIds.length) {
5
5
  throw new Error('@file-viewer/renderer-media could not locate the shared audio/video format definitions.');
6
6
  }
7
7
  export const mediaRendererDefinitions = mediaDefinitions;
8
- export const renderFileViewerAudio = (buffer, target, type) => import('./audio.js').then(({ default: renderAudio }) => renderAudio(buffer, target, type));
8
+ export const renderFileViewerAudio = (buffer, target, type, context) => import('./audio.js').then(({ default: renderAudio }) => renderAudio(buffer, target, type, context));
9
9
  export const renderFileViewerVideo = (buffer, target, type, context) => import('./video.js').then(({ default: renderVideo }) => renderVideo(buffer, target, type, context));
10
10
  export const mediaRenderer = {
11
11
  id: 'file-viewer-renderer-media',
package/dist/video.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { FileRenderContext, FileViewerRenderedInstance } from '@file-viewer/core';
1
+ import { type FileRenderContext, type FileViewerRenderedInstance } from '@file-viewer/core';
2
2
  /**
3
3
  * Pure TypeScript video renderer.
4
4
  *
package/dist/video.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createFileViewerTranslator } from '@file-viewer/core';
1
2
  const videoStyle = `
2
3
  .fv-video-viewer{width:100%;min-height:100%;display:flex;align-items:center;justify-content:center;padding:28px;background:#eef1f4;box-sizing:border-box}
3
4
  .fv-video-shell{width:min(100%,960px);border-radius:8px;border:1px solid rgba(15,23,42,.1);background:#fff;box-shadow:0 18px 48px rgba(15,23,42,.14);overflow:hidden}
@@ -47,6 +48,7 @@ const createLocalUrl = (buffer, type) => {
47
48
  * first and imports `hls.js` only when the current browser needs it.
48
49
  */
49
50
  export default async function renderVideo(buffer, target, type, context) {
51
+ const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
50
52
  const normalizedType = (type || 'mp4').toLowerCase();
51
53
  let disposed = false;
52
54
  let objectUrl = '';
@@ -54,14 +56,14 @@ export default async function renderVideo(buffer, target, type, context) {
54
56
  const root = createElement('div', 'fv-video-viewer');
55
57
  const shell = createElement('section', 'fv-video-shell');
56
58
  const heading = createElement('div', 'fv-video-heading');
57
- heading.append(createElement('span', '', normalizedType.toUpperCase() || 'VIDEO'), createElement('strong', '', '视频预览'));
59
+ heading.append(createElement('span', '', normalizedType.toUpperCase() || 'VIDEO'), createElement('strong', '', t('media.video.title')));
58
60
  const video = createElement('video', 'fv-video-player');
59
61
  video.controls = true;
60
62
  video.preload = 'metadata';
61
- video.textContent = '当前浏览器不支持该视频格式。';
63
+ video.textContent = t('media.video.unsupported');
62
64
  shell.append(heading, video);
63
65
  if (normalizedType === 'm3u8') {
64
- shell.append(createElement('p', 'fv-video-hint', 'HLS 会优先使用原始 URL 加载分片;如果传入的是本地单文件清单,请确保分片地址可被浏览器访问。'));
66
+ shell.append(createElement('p', 'fv-video-hint', t('media.video.hlsHint')));
65
67
  }
66
68
  root.append(shell);
67
69
  target.replaceChildren(createStyle(), root);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/renderer-media",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone audio and video renderer plugin for Flyfish File Viewer with native media playback, HLS fallback, MIDI parsing, and offline-friendly lazy loading.",
@@ -55,7 +55,7 @@
55
55
  "LICENSE"
56
56
  ],
57
57
  "dependencies": {
58
- "@file-viewer/core": "^2.1.1",
58
+ "@file-viewer/core": "^2.1.3",
59
59
  "@tonejs/midi": "^2.0.28",
60
60
  "hls.js": "^1.6.16"
61
61
  },