hls-streamer 3.0.0 → 4.0.0

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.
Files changed (80) hide show
  1. package/README.md +148 -92
  2. package/dist/Interfaces/HlsStreamer.d.ts +4 -3
  3. package/dist/Interfaces/HlsStreamer.d.ts.map +1 -1
  4. package/dist/Libs/FileLib.d.ts +11 -5
  5. package/dist/Libs/FileLib.d.ts.map +1 -1
  6. package/dist/Libs/FileLib.js +9 -3
  7. package/dist/Libs/FileLib.js.map +1 -1
  8. package/dist/Libs/FormatDetector.d.ts +3 -3
  9. package/dist/Libs/FormatDetector.d.ts.map +1 -1
  10. package/dist/Libs/FormatDetector.js +31 -7
  11. package/dist/Libs/FormatDetector.js.map +1 -1
  12. package/dist/Parsers/AacParser.d.ts +4 -4
  13. package/dist/Parsers/AacParser.d.ts.map +1 -1
  14. package/dist/Parsers/AacParser.js +5 -1
  15. package/dist/Parsers/AacParser.js.map +1 -1
  16. package/dist/Parsers/FlacParser.d.ts +4 -4
  17. package/dist/Parsers/IAudioParser.d.ts +1 -30
  18. package/dist/Parsers/IAudioParser.d.ts.map +1 -1
  19. package/dist/Parsers/IMediaParser.d.ts +43 -0
  20. package/dist/Parsers/IMediaParser.d.ts.map +1 -0
  21. package/dist/Parsers/IMediaParser.js +2 -0
  22. package/dist/Parsers/IMediaParser.js.map +1 -0
  23. package/dist/Parsers/Mp3Parser.d.ts +4 -4
  24. package/dist/Parsers/Mp3Parser.js +8 -8
  25. package/dist/Parsers/Mp3Parser.js.map +1 -1
  26. package/dist/Parsers/Mp4Parser.d.ts +21 -0
  27. package/dist/Parsers/Mp4Parser.d.ts.map +1 -0
  28. package/dist/Parsers/Mp4Parser.js +418 -0
  29. package/dist/Parsers/Mp4Parser.js.map +1 -0
  30. package/dist/Parsers/OggParser.d.ts +4 -4
  31. package/dist/Parsers/ParserFactory.d.ts +5 -5
  32. package/dist/Parsers/ParserFactory.d.ts.map +1 -1
  33. package/dist/Parsers/ParserFactory.js +6 -3
  34. package/dist/Parsers/ParserFactory.js.map +1 -1
  35. package/dist/Parsers/WavParser.d.ts +4 -4
  36. package/dist/cjs/Interfaces/HlsStreamer.d.ts +4 -3
  37. package/dist/cjs/Interfaces/HlsStreamer.d.ts.map +1 -1
  38. package/dist/cjs/Libs/FileLib.d.ts +11 -5
  39. package/dist/cjs/Libs/FileLib.d.ts.map +1 -1
  40. package/dist/cjs/Libs/FileLib.js +9 -3
  41. package/dist/cjs/Libs/FileLib.js.map +1 -1
  42. package/dist/cjs/Libs/FormatDetector.d.ts +3 -3
  43. package/dist/cjs/Libs/FormatDetector.d.ts.map +1 -1
  44. package/dist/cjs/Libs/FormatDetector.js +31 -7
  45. package/dist/cjs/Libs/FormatDetector.js.map +1 -1
  46. package/dist/cjs/Parsers/AacParser.d.ts +4 -4
  47. package/dist/cjs/Parsers/AacParser.d.ts.map +1 -1
  48. package/dist/cjs/Parsers/AacParser.js +5 -1
  49. package/dist/cjs/Parsers/AacParser.js.map +1 -1
  50. package/dist/cjs/Parsers/FlacParser.d.ts +4 -4
  51. package/dist/cjs/Parsers/IAudioParser.d.ts +1 -30
  52. package/dist/cjs/Parsers/IAudioParser.d.ts.map +1 -1
  53. package/dist/cjs/Parsers/IMediaParser.d.ts +43 -0
  54. package/dist/cjs/Parsers/IMediaParser.d.ts.map +1 -0
  55. package/dist/cjs/Parsers/IMediaParser.js +3 -0
  56. package/dist/cjs/Parsers/IMediaParser.js.map +1 -0
  57. package/dist/cjs/Parsers/Mp3Parser.d.ts +4 -4
  58. package/dist/cjs/Parsers/Mp3Parser.js +8 -8
  59. package/dist/cjs/Parsers/Mp3Parser.js.map +1 -1
  60. package/dist/cjs/Parsers/Mp4Parser.d.ts +21 -0
  61. package/dist/cjs/Parsers/Mp4Parser.d.ts.map +1 -0
  62. package/dist/cjs/Parsers/Mp4Parser.js +422 -0
  63. package/dist/cjs/Parsers/Mp4Parser.js.map +1 -0
  64. package/dist/cjs/Parsers/OggParser.d.ts +4 -4
  65. package/dist/cjs/Parsers/ParserFactory.d.ts +5 -5
  66. package/dist/cjs/Parsers/ParserFactory.d.ts.map +1 -1
  67. package/dist/cjs/Parsers/ParserFactory.js +6 -3
  68. package/dist/cjs/Parsers/ParserFactory.js.map +1 -1
  69. package/dist/cjs/Parsers/WavParser.d.ts +4 -4
  70. package/dist/cjs/errors/HlsStreamerErrors.js +1 -1
  71. package/dist/cjs/index.d.ts +1 -0
  72. package/dist/cjs/index.d.ts.map +1 -1
  73. package/dist/cjs/index.js +35 -9
  74. package/dist/cjs/index.js.map +1 -1
  75. package/dist/errors/HlsStreamerErrors.js +1 -1
  76. package/dist/index.d.ts +1 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +35 -9
  79. package/dist/index.js.map +1 -1
  80. package/package.json +8 -3
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](https://www.typescriptlang.org/)
6
6
 
7
- HLS Streamer turns any audio file (MP3, AAC, M4A, OGG Vorbis, FLAC, WAV) into an HTTP Live Streaming (HLS) playlist on the fly. It analyses the source audio in-memory, builds frame-aligned byte ranges, and streams them without temporary files, native bindings, or external binaries like ffmpeg.
7
+ HLS Streamer converts audio and video files (MP3, AAC, M4A, OGG Vorbis, FLAC, WAV, MP4, MOV, M4V) into HTTP Live Streaming (HLS) playlists on the fly. It analyses the source file in-memory, builds frame-aligned byte ranges, and streams them without temporary files, native bindings, or external binaries like ffmpeg.
8
8
 
9
9
  ---
10
10
 
@@ -16,30 +16,32 @@ HLS Streamer turns any audio file (MP3, AAC, M4A, OGG Vorbis, FLAC, WAV) into an
16
16
  - [Playlist Anatomy](#playlist-anatomy)
17
17
  - [Operational Tips](#operational-tips)
18
18
  - [Development](#development)
19
+ - [Release Notes](#release-notes)
19
20
  - [Support](#support)
20
21
 
21
22
  ## Why HLS Streamer?
22
23
 
23
- - **Multi-format support** – handles MP3, AAC, M4A, OGG Vorbis, FLAC, and WAV with automatic format detection.
24
+ - **Multi-format support** – handles MP3, AAC, M4A, OGG Vorbis, FLAC, WAV, MP4, MOV, and M4V with automatic format detection.
25
+ - **Audio + Video** – audio files produce standard HLS v6 playlists; video files produce HLS v7 fMP4 playlists with an `EXT-X-MAP` init segment and keyframe-aligned boundaries.
24
26
  - **Zero dependencies** – no shared libraries, no ffmpeg, no native compilation. Pure TypeScript parsers for all formats. Drop it into Docker, serverless, or edge runtimes.
25
- - **Accurate segments** – real audio frame/packet parsing provides true durations, `#EXTINF` metadata, and target durations that match playback.
26
- - **Frame-aligned byte ranges** – every segment begins and ends on verified frame/packet boundaries, preventing pops and clipped audio.
27
- - **No temp files** – streams straight from the source audio file using byte-range reads.
27
+ - **Accurate segments** – real frame/packet parsing provides true durations, `#EXTINF` metadata, and target durations that match playback.
28
+ - **Frame-aligned byte ranges** – every segment begins and ends on verified frame boundaries; video segments snap to keyframes to prevent decoding artifacts.
29
+ - **No temp files** – streams straight from the source file using byte-range reads.
28
30
  - **Fast-start aware** – optional smaller first segments improve startup latency for constrained networks.
29
31
  - **TypeScript first** – authored in TypeScript with full type definitions for your tooling and IDEs.
30
32
 
31
33
  ## How It Works
32
34
 
33
- 1. **Format detection** – automatically detects audio format from file content (magic bytes) or extension, with optional manual override.
34
- 2. **Metadata analysis** – format-specific parsers extract metadata (ID3/Vorbis comments/etc.), parse frame/packet headers, and produce a frame table with offsets, durations, and bitrates.
35
- 3. **Segment planning** – segment boundaries are calculated from the frame table so each segment contains whole frames/packets while matching your target sizes.
36
- 4. **Playlist generation** – `createM3U8()` emits an `#EXTM3U` playlist with accurate `#EXTINF` entries and `#EXT-X-TARGETDURATION` derived from the longest segment.
37
- 5. **On-demand byte ranges** – `getFileBuffer(start, end)` streams the exact bytes for a segment without reading the entire file into memory.
35
+ 1. **Format detection** – automatically detects format from file content (magic bytes / `ftyp` brand) or extension, with optional manual override.
36
+ 2. **Metadata analysis** – format-specific parsers extract frame/packet tables with offsets, durations, and (for video) keyframe markers.
37
+ 3. **Segment planning** – boundaries are calculated from the frame table so each segment contains whole frames while respecting your target size. Video segments snap to I-frame boundaries.
38
+ 4. **Playlist generation** – `createM3U8()` emits an `#EXTM3U` playlist. Audio files use HLS v6; video files use HLS v7 with `EXT-X-MAP` pointing to the `moov` init segment.
39
+ 5. **On-demand byte ranges** – `getFileBuffer(start, end)` reads only the bytes needed for a given segment or init segment.
38
40
 
39
41
  ```
40
42
  ┌──────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────────┐
41
- Audio Source │ ──▶ │ Format Detector │ ──▶ │ Format Parser │ ──▶ │ Segment Planner │
42
- │ (any format) │ │ (magic bytes) │ │ (MP3/AAC/etc.) │ │ (frame-aligned)
43
+ Media Source │ ──▶ │ Format Detector │ ──▶ │ Format Parser │ ──▶ │ Segment Planner │
44
+ │ (any format) │ │ (magic bytes) │ │ (MP3/MP4/etc.) │ │ (frame/keyframe)
43
45
  └──────────────┘ └─────────────────┘ └─────────────────┘ └──────────┬───────────┘
44
46
 
45
47
 
@@ -53,25 +55,34 @@ HLS Streamer turns any audio file (MP3, AAC, M4A, OGG Vorbis, FLAC, WAV) into an
53
55
  ```ts
54
56
  import { HlsStreamer } from 'hls-streamer';
55
57
 
56
- // Works with any supported format - auto-detected!
57
- const streamer = new HlsStreamer({
58
+ // Audio file auto-detected
59
+ const audioStreamer = new HlsStreamer({
58
60
  filePath: '/media/library/song.mp3', // or .aac, .m4a, .ogg, .flac, .wav
59
61
  segmentSizeKB: 512,
60
62
  fileName: 'track',
61
63
  baseUrl: 'audio/stream/session-42',
62
64
  enableFastStart: true,
63
- // format: 'mp3' // optional: override auto-detection
64
65
  });
65
66
 
66
- const playlist = await streamer.createM3U8();
67
- console.log(playlist);
67
+ const audioPlaylist = await audioStreamer.createM3U8();
68
68
 
69
- const firstSegmentBuffer = await streamer.getFileBuffer(0, 512 * 1024);
69
+ // Video file same API
70
+ const videoStreamer = new HlsStreamer({
71
+ filePath: '/media/library/movie.mp4', // or .mov, .m4v
72
+ segmentSizeKB: 2048,
73
+ fileName: 'segment',
74
+ baseUrl: 'video/stream/session-42',
75
+ });
76
+
77
+ const videoPlaylist = await videoStreamer.createM3U8();
78
+
79
+ // Detect media type at runtime
80
+ const type = await videoStreamer.getMediaType(); // 'video' | 'audio'
70
81
  ```
71
82
 
72
83
  ## Serving Over HTTP
73
84
 
74
- Create playlists and segment endpoints with any HTTP framework. The example below shows an Express setup:
85
+ The example below shows an Express setup that handles both audio and video:
75
86
 
76
87
  ```ts
77
88
  import express from 'express';
@@ -82,7 +93,7 @@ const app = express();
82
93
  app.get('/streams/:id/playlist.m3u8', async (req, res, next) => {
83
94
  try {
84
95
  const streamer = new HlsStreamer({
85
- filePath: resolveAudioPath(req.params.id),
96
+ filePath: resolveMediaPath(req.params.id),
86
97
  baseUrl: `streams/${req.params.id}`,
87
98
  enableFastStart: true,
88
99
  });
@@ -97,14 +108,15 @@ app.get('/streams/:id/playlist.m3u8', async (req, res, next) => {
97
108
  app.get('/streams/:id/:start/:end/:filename', async (req, res, next) => {
98
109
  try {
99
110
  const streamer = new HlsStreamer({
100
- filePath: resolveAudioPath(req.params.id),
111
+ filePath: resolveMediaPath(req.params.id),
101
112
  baseUrl: `streams/${req.params.id}`,
102
113
  });
103
114
 
104
115
  const start = Number(req.params.start);
105
116
  const end = Number(req.params.end);
117
+ const mediaType = await streamer.getMediaType();
106
118
 
107
- res.type('audio/mpeg');
119
+ res.type(mediaType === 'video' ? 'video/mp4' : 'audio/mpeg');
108
120
  res.set('Accept-Ranges', 'bytes');
109
121
  res.send(await streamer.getFileBuffer(start, end));
110
122
  } catch (error) {
@@ -115,48 +127,60 @@ app.get('/streams/:id/:start/:end/:filename', async (req, res, next) => {
115
127
 
116
128
  ### Segment URL Contract
117
129
 
118
- Generated playlists follow the pattern below:
130
+ Generated playlists follow this pattern:
131
+
132
+ ```
133
+ /{baseUrl}/{startByte}/{endByte}/{fileName}{index}.{ext}
134
+ ```
135
+
136
+ For video files, an additional init segment URL is emitted as `EXT-X-MAP`:
119
137
 
120
138
  ```
121
- /{baseUrl}/{startByte}/{endByte}/{fileName}{index}.mp3
139
+ /{baseUrl}/{moovOffset}/{moovEnd}/{fileName}init.mp4
122
140
  ```
123
141
 
124
142
  - `startByte` is inclusive, `endByte` is exclusive.
125
143
  - `index` is zero-padded to three digits (`000`, `001`, ...).
126
- - Use the provided byte range as-is when serving `audio/mpeg` responses.
144
+ - Serve the exact byte range from the original file — no transcoding needed.
127
145
 
128
146
  ## Configuration Reference
129
147
 
130
- | Option | Type | Default | Description |
131
- | ------------------- | --------- | ------- | ----------- |
132
- | `filePath` | `string` | — | Absolute or relative path to the audio file. Supports: MP3, AAC, M4A, OGG, FLAC, WAV. |
133
- | `segmentSizeKB` | `number` | `512` | Target segment size in kilobytes. Fast-start mode splits the first two segments into quarters/halves of this value. |
134
- | `fileName` | `string` | `"file"` | Base name used in generated segment URLs (the index is appended automatically). |
135
- | `baseUrl` | `string` | `""` | URL prefix inserted before each segment path. Useful when mounting under a route or CDN prefix. |
136
- | `enableFastStart` | `boolean` | `false` | When true, the first two segments are smaller to reduce initial buffering time. |
137
- | `format` | `AudioFormat` | auto-detect | Optional format override ('mp3', 'aac', 'm4a', 'ogg', 'flac', 'wav'). Auto-detected from file if not specified. |
148
+ | Option | Type | Default | Description |
149
+ | ----------------- | ------------- | ------------ | ----------- |
150
+ | `filePath` | `string` | — | Path to the media file. Supports: MP3, AAC, M4A, OGG, FLAC, WAV, MP4, MOV, M4V. |
151
+ | `segmentSizeKB` | `number` | `512` | Target segment size in kilobytes. |
152
+ | `fileName` | `string` | `"file"` | Base name for generated segment URLs. |
153
+ | `baseUrl` | `string` | `""` | URL prefix inserted before each segment path. |
154
+ | `enableFastStart` | `boolean` | `false` | Smaller first two segments for faster playback start. |
155
+ | `format` | `MediaFormat` | auto-detect | Optional override: `'mp3'`, `'aac'`, `'m4a'`, `'ogg'`, `'flac'`, `'wav'`, `'mp4'`, `'mov'`, `'m4v'`. |
138
156
 
139
157
  ### API Surface
140
158
 
141
- - `createM3U8(): Promise<string>` – Returns a full playlist with frame-accurate durations.
142
- - `getFileBuffer(start: number, end: number): Promise<Buffer>` – Streams a byte range from the audio file.
143
- - `getSegmentDuration(index: number): Promise<number>` – Reads the cached segment table to return the duration of a segment in seconds.
159
+ - `createM3U8(): Promise<string>` – Full HLS playlist with frame-accurate durations. Audio → HLS v6; Video → HLS v7 + `EXT-X-MAP`.
160
+ - `getFileBuffer(start: number, end: number): Promise<Buffer>` – Byte-range read from the source file (used for both segments and the init segment).
161
+ - `getSegmentDuration(index: number): Promise<number>` – Duration in seconds for a specific segment.
162
+ - `getMediaType(): Promise<'audio' | 'video'>` – Returns `'video'` for MP4/MOV/M4V, `'audio'` for everything else.
144
163
 
145
- Custom error classes are exported to help with error handling: `FileNotFoundError`, `InvalidFileError`, `InvalidRangeError`, `InvalidParameterError`, and `UnsupportedFormatError`.
164
+ Custom error classes: `FileNotFoundError`, `InvalidFileError`, `InvalidRangeError`, `InvalidParameterError`, `UnsupportedFormatError`.
146
165
 
147
166
  ### Supported Formats
148
167
 
149
- | Format | Extensions | Container | Codec | Frame Parsing |
150
- |--------|-----------|-----------|-------|---------------|
151
- | **MP3** | `.mp3` | — | MPEG-1/2 Layer III | ✅ Full frame table |
152
- | **AAC** | `.aac` | ADTS | AAC | ✅ ADTS frames |
153
- | **M4A** | `.m4a`, `.m4b` | MP4 | AAC | ✅ MP4 box structure |
154
- | **OGG** | `.ogg`, `.oga` | OGG | Vorbis | ✅ OGG pages |
155
- | **FLAC** | `.flac` | — | FLAC | ✅ FLAC frames |
156
- | **WAV** | `.wav` | RIFF | PCM | ⚠️ Synthetic 1-second frames |
168
+ | Format | Extensions | Container | Codec | Frame Parsing |
169
+ | ------- | ------------------- | --------- | ------------ | ------------------------------- |
170
+ | **MP3** | `.mp3` | — | MPEG Layer 3 | ✅ Full frame table |
171
+ | **AAC** | `.aac` | ADTS | AAC | ✅ ADTS frames |
172
+ | **M4A** | `.m4a`, `.m4b` | MP4 | AAC | ✅ MP4 box structure |
173
+ | **OGG** | `.ogg`, `.oga` | OGG | Vorbis | ✅ OGG pages |
174
+ | **FLAC**| `.flac` | — | FLAC | ✅ FLAC frames |
175
+ | **WAV** | `.wav` | RIFF | PCM | ⚠️ Synthetic 1-second frames |
176
+ | **MP4** | `.mp4` | fMP4 | H.264/H.265 | ✅ ISOBMFF box parse + keyframes |
177
+ | **MOV** | `.mov` | QuickTime | H.264/H.265 | ✅ ISOBMFF box parse + keyframes |
178
+ | **M4V** | `.m4v` | MP4 | H.264/H.265 | ✅ ISOBMFF box parse + keyframes |
157
179
 
158
180
  ## Playlist Anatomy
159
181
 
182
+ ### Audio (HLS v6)
183
+
160
184
  ```m3u8
161
185
  #EXTM3U
162
186
  #EXT-X-VERSION:6
@@ -171,36 +195,49 @@ Custom error classes are exported to help with error handling: `FileNotFoundErro
171
195
  #EXT-X-ENDLIST
172
196
  ```
173
197
 
174
- - `#EXT-X-TARGETDURATION` is rounded up from the longest real segment duration.
175
- - `#EXTINF` entries retain millisecond precision for smooth playback on strict clients.
176
- - Segment paths directly encode the byte ranges your route must return.
198
+ ### Video (HLS v7 fMP4)
199
+
200
+ ```m3u8
201
+ #EXTM3U
202
+ #EXT-X-VERSION:7
203
+ #EXT-X-PLAYLIST-TYPE:VOD
204
+ #EXT-X-TARGETDURATION:4
205
+ #EXT-X-MEDIA-SEQUENCE:0
206
+ #EXT-X-MAP:URI="/video/session/0/28672/fileinit.mp4"
207
+ #EXTINF:4.000,
208
+ /video/session/28672/2125824/file000.mp4
209
+ #EXTINF:3.967,
210
+ /video/session/2125824/4194304/file001.mp4
211
+ ...
212
+ #EXT-X-ENDLIST
213
+ ```
214
+
215
+ - `EXT-X-MAP` points to the `moov` box (init segment) inside the original file — no remuxing.
216
+ - Video segment boundaries are snapped to keyframes for seamless decoding.
217
+ - `#EXTINF` retains millisecond precision for smooth playback.
177
218
 
178
219
  ## Operational Tips
179
220
 
180
- - **Caching** – Construct the streamer once per unique audio file and reuse it. Segment planning caches the metadata, so repeated calls to `createM3U8()` or `getSegmentDuration()` are cheap.
181
- - **CDN friendliness** – Because segment URLs are deterministic byte ranges, edge caches can serve them efficiently. Configure consistent caching headers (e.g. `Cache-Control: public, max-age=86400`).
182
- - **Serverless** – The zero-dependency design works well in Lambda/Cloud Functions. For large files, prefer streaming reads (`getFileBuffer`) instead of loading entire files into memory.
183
- - **Monitoring** – Log segment `start`/`end` pairs and durations to correlate playback issues with specific byte ranges or frame parsing warnings.
184
- - **Troubleshooting** – For corrupted files, inspect `FileLib.analyzeAudioFile()` to review parsing warnings and format-specific metadata.
185
- - **Format selection** – All formats work seamlessly with HLS, but consider:
186
- - **MP3/AAC/M4A**: Best compatibility with HLS players
187
- - **FLAC**: Lossless quality but larger segments
188
- - **OGG**: Open-source, good compression
189
- - **WAV**: Uncompressed, very large segments (consider smaller `segmentSizeKB`)
221
+ - **Caching** – Construct the streamer once per unique file and reuse it. Segment planning caches metadata after the first call.
222
+ - **Video segment size** – Use a larger `segmentSizeKB` (1024–4096) for video to avoid excessive HTTP requests. Audio works well at 512.
223
+ - **CDN friendliness** – Segment URLs are deterministic byte ranges, making them ideal for edge caching. Use `Cache-Control: public, max-age=86400`.
224
+ - **Serverless** – Zero-dependency design works in Lambda/Cloud Functions. `getFileBuffer` reads only the bytes needed, keeping memory usage low.
225
+ - **Content-Type** – Serve audio segments as `audio/mpeg` (or the appropriate codec MIME type) and video segments as `video/mp4`. Use `getMediaType()` to branch at runtime.
226
+ - **Troubleshooting** – Inspect `FileLib.analyzeMediaFile()` to review parsing warnings and format-specific metadata.
190
227
 
191
228
  ## Development
192
229
 
193
- Clone the repo, install dependencies, and run the usual scripts:
194
-
195
230
  ```bash
196
231
  npm install
197
- npm test -- --runInBand --watchman=false
232
+ npm test
198
233
  npm run build
199
234
  ```
200
235
 
201
- The Jest flag `--watchman=false` avoids macOS sandbox issues when running in restricted environments.
236
+ To run a single test file:
202
237
 
203
- To explore the example playlist generator, see `example/test-hls-generation.js` and the bundled `example/sample.mp3` fixture.
238
+ ```bash
239
+ npx jest tests/Parsers/Mp4Parser.test.ts
240
+ ```
204
241
 
205
242
  ## Support
206
243
 
@@ -210,45 +247,64 @@ To explore the example playlist generator, see `example/test-hls-generation.js`
210
247
 
211
248
  ## Contributing
212
249
 
213
- Contributions are welcome! Please open an issue to discuss substantial changes before submitting a pull request. Make sure `npm test -- --runInBand --watchman=false` and `npm run build` pass prior to filing the PR.
250
+ Contributions are welcome! Please open an issue to discuss substantial changes before submitting a pull request. Make sure `npm test` and `npm run build` pass prior to filing the PR.
214
251
 
215
252
  ---
216
253
 
217
- ## Version 3.0.0 Breaking Changes
254
+ ## Release Notes
218
255
 
219
- This major release adds multi-format support with pure TypeScript parsers. While most code remains backward compatible, please note:
256
+ ### Version 4.0.0
220
257
 
221
- ### What Changed
222
- - **New formats**: Added AAC, M4A, OGG Vorbis, FLAC, and WAV support
223
- - **Format detection**: Files are now validated against all supported formats, not just MP3
224
- - **Error types**: `InvalidFileError` for non-MP3 files is now `UnsupportedFormatError` for unsupported formats
225
- - **Internal architecture**: MP3 parsing refactored into modular `Parsers/` directory
258
+ Major release adding video support and completing the audio→media rename.
259
+
260
+ #### New Features
261
+ - **Video support** MP4, MOV, and M4V files are now fully supported via a pure-JS ISOBMFF (MP4 box) parser. No ffmpeg, no native bindings, no vendored libraries.
262
+ - **HLS v7 fMP4 playlists** video files produce `EXT-X-MAP` init segments and keyframe-aligned byte-range segments, fully compatible with Safari, Chrome, and HLS.js.
263
+ - **Keyframe-aware segmentation** – video segment boundaries snap to I-frames, preventing decoding artifacts.
264
+ - **`getMediaType()`** – new method returning `'audio' | 'video'` to simplify route/MIME-type logic.
265
+ - **`MediaFormat` / `MediaFileInfo` / `MediaFrameInfo`** – public types renamed from `Audio*` to `Media*` to reflect the broader scope.
266
+
267
+ #### Breaking Changes (from v3)
268
+ - `AudioFormat`, `AudioFileInfo`, `AudioFrameInfo`, `IAudioParser` are now **deprecated** aliases — they still compile but will be removed in v5.
269
+ - `FileLib.analyzeAudioFile()` and `analyzeAudioBuffer()` are deprecated; use `analyzeMediaFile()` / `analyzeMediaBuffer()`.
270
+ - `UnsupportedFormatError` message changed from `"Unsupported audio format"` to `"Unsupported media format"`.
271
+ - `format` option type widened from `AudioFormat` to `MediaFormat` (superset — no change needed for existing callers).
272
+
273
+ #### Migration Guide
226
274
 
227
- ### Migration Guide
228
275
  ```typescript
229
- // v2.x - Only MP3 supported
230
- const streamer = new HlsStreamer({ filePath: 'song.mp3' });
231
-
232
- // v3.x - All formats work the same way!
233
- const streamer = new HlsStreamer({ filePath: 'song.mp3' }); // ✅ Still works
234
- const streamer = new HlsStreamer({ filePath: 'song.ogg' }); // ✅ Now supported
235
- const streamer = new HlsStreamer({ filePath: 'song.flac' }); // Now supported
236
-
237
- // Error handling update
238
- try {
239
- new HlsStreamer({ filePath: 'document.pdf' });
240
- } catch (err) {
241
- // v2.x: InvalidFileError
242
- // v3.x: UnsupportedFormatError
243
- }
276
+ // v3.x
277
+ import { AudioFormat, AudioFileInfo } from 'hls-streamer';
278
+ const type: AudioFormat = 'mp3';
279
+
280
+ // v4.x preferred
281
+ import { MediaFormat, MediaFileInfo } from 'hls-streamer';
282
+ const type: MediaFormat = 'mp3'; // same values, broader type
283
+
284
+ // v3.x names still compile in v4 (deprecated, removed in v5)
285
+ import { AudioFormat } from 'hls-streamer'; // ⚠️ deprecated alias
286
+
287
+ // Video new in v4
288
+ const streamer = new HlsStreamer({ filePath: 'movie.mp4' });
289
+ const playlist = await streamer.createM3U8(); // HLS v7 + EXT-X-MAP
290
+ const type = await streamer.getMediaType(); // 'video'
244
291
  ```
245
292
 
246
- ### Deprecated APIs
247
- - `Mp3FileInfo` → Use `AudioFileInfo` (backward compatible, but deprecated)
248
- - `Mp3FrameInfo` → Use `AudioFrameInfo` (backward compatible, but deprecated)
249
- - `FileLib.analyzeMP3File()` → Use `FileLib.analyzeAudioFile()` (old method still works)
293
+ ---
294
+
295
+ ### Version 3.1.0
296
+
297
+ - **HLS compliance**: `#EXTINF` lines now include the required trailing comma.
298
+ - **AAC ADTS detection**: ADTS buffers no longer misclassified as MP3.
299
+ - **Extensionless files**: constructor now accepts extensionless files when magic bytes identify a supported format.
300
+
301
+ ---
302
+
303
+ ### Version 3.0.0
250
304
 
251
- All deprecated APIs remain functional for backward compatibility but will be removed in v4.0.0.
305
+ - Added AAC, M4A, OGG Vorbis, FLAC, and WAV support.
306
+ - Refactored MP3 parsing into a modular `Parsers/` directory.
307
+ - `InvalidFileError` for non-MP3 files replaced by `UnsupportedFormatError`.
252
308
 
253
309
  ---
254
310
 
@@ -1,18 +1,19 @@
1
- import { AudioFormat } from '../Parsers/IAudioParser';
1
+ import { MediaFormat } from '../Parsers/IMediaParser';
2
2
  export interface HlsStreamerOptions {
3
3
  filePath: string;
4
4
  segmentSizeKB?: number;
5
5
  fileName?: string;
6
6
  baseUrl?: string;
7
7
  enableFastStart?: boolean;
8
- format?: AudioFormat;
8
+ format?: MediaFormat;
9
9
  }
10
10
  export interface SegmentInfo {
11
11
  start: number;
12
12
  end: number;
13
13
  duration: number;
14
14
  }
15
- export type { AudioFormat, AudioFrameInfo, AudioFileInfo } from '../Parsers/IAudioParser';
15
+ export type { MediaFormat, MediaFrameInfo, MediaFileInfo, IMediaParser } from '../Parsers/IMediaParser';
16
+ export type { AudioFormat, AudioFrameInfo, AudioFileInfo, IAudioParser } from '../Parsers/IMediaParser';
16
17
  export interface Mp3FrameInfo {
17
18
  index: number;
18
19
  offset: number;
@@ -1 +1 @@
1
- {"version":3,"file":"HlsStreamer.d.ts","sourceRoot":"","sources":["../../src/Interfaces/HlsStreamer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IAEjC,QAAQ,EAAE,MAAM,CAAC;IAEjB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAKD,MAAM,WAAW,WAAW;IAE1B,KAAK,EAAE,MAAM,CAAC;IAEd,GAAG,EAAE,MAAM,CAAC;IAEZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAM1F,MAAM,WAAW,YAAY;IAI3B,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,MAAM,CAAC;IAEf,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB;AAMD,MAAM,WAAW,WAAW;IAE1B,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,EAAE,MAAM,CAAC;IAEjB,aAAa,EAAE,MAAM,CAAC;IAEtB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,YAAY,EAAE,CAAC;IAEvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
1
+ {"version":3,"file":"HlsStreamer.d.ts","sourceRoot":"","sources":["../../src/Interfaces/HlsStreamer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,MAAM,WAAW,kBAAkB;IAEjC,QAAQ,EAAE,MAAM,CAAC;IAEjB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAKD,MAAM,WAAW,WAAW;IAE1B,KAAK,EAAE,MAAM,CAAC;IAEd,GAAG,EAAE,MAAM,CAAC;IAEZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGxG,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKxG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB;AAKD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -1,5 +1,5 @@
1
- import { Mp3FileInfo, AudioFileInfo } from '../Interfaces/HlsStreamer';
2
- import { AudioFormat } from '../Parsers/IAudioParser';
1
+ import { Mp3FileInfo, MediaFileInfo } from '../Interfaces/HlsStreamer';
2
+ import { MediaFormat } from '../Parsers/IMediaParser';
3
3
  export declare class FileLib {
4
4
  private static readonly BITRATE_INDEX;
5
5
  private static readonly SAMPLE_RATE_INDEX;
@@ -9,12 +9,18 @@ export declare class FileLib {
9
9
  fileSize?: number;
10
10
  }): Mp3FileInfo;
11
11
  static analyzeMP3File(filePath: string): Promise<Mp3FileInfo>;
12
- static analyzeAudioFile(filePath: string, format?: AudioFormat): Promise<AudioFileInfo>;
12
+ static analyzeMediaFile(filePath: string, format?: MediaFormat): Promise<MediaFileInfo>;
13
+ static analyzeAudioFile(filePath: string, format?: MediaFormat): Promise<MediaFileInfo>;
14
+ static analyzeMediaBuffer(buffer: Buffer, opts?: {
15
+ fileSize?: number;
16
+ filePath?: string;
17
+ format?: MediaFormat;
18
+ }): MediaFileInfo;
13
19
  static analyzeAudioBuffer(buffer: Buffer, opts?: {
14
20
  fileSize?: number;
15
21
  filePath?: string;
16
- format?: AudioFormat;
17
- }): AudioFileInfo;
22
+ format?: MediaFormat;
23
+ }): MediaFileInfo;
18
24
  private static calculateFrameLength;
19
25
  private static getId3Offsets;
20
26
  private static syncSafeInteger;
@@ -1 +1 @@
1
- {"version":3,"file":"FileLib.d.ts","sourceRoot":"","sources":["../../src/Libs/FileLib.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAgB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAGrF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAqBtD,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAgBnC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAIvC;IAKF,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;WAWpC,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzE,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,WAAW;WA8HzE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;WAetD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAwB7F,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACxE,aAAa;IA6BhB,OAAO,CAAC,MAAM,CAAC,oBAAoB;IASnC,OAAO,CAAC,MAAM,CAAC,aAAa;IA8B5B,OAAO,CAAC,MAAM,CAAC,eAAe;IAO9B,OAAO,CAAC,MAAM,CAAC,WAAW;IAW1B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAqC/B,OAAO,CAAC,MAAM,CAAC,aAAa;IAa5B,OAAO,CAAC,MAAM,CAAC,WAAW;IAa1B,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAWlC"}
1
+ {"version":3,"file":"FileLib.d.ts","sourceRoot":"","sources":["../../src/Libs/FileLib.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAgB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAGrF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAqBtD,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAgBnC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAIvC;IAKF,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;WAWpC,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzE,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,WAAW;WA8HzE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;WAetD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;WAmBhF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAU7F,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACxE,aAAa;IA8BhB,MAAM,CAAC,kBAAkB,CACvB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACxE,aAAa;IAIhB,OAAO,CAAC,MAAM,CAAC,oBAAoB;IASnC,OAAO,CAAC,MAAM,CAAC,aAAa;IA8B5B,OAAO,CAAC,MAAM,CAAC,eAAe;IAO9B,OAAO,CAAC,MAAM,CAAC,WAAW;IAW1B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAqC/B,OAAO,CAAC,MAAM,CAAC,aAAa;IAa5B,OAAO,CAAC,MAAM,CAAC,WAAW;IAa1B,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAWlC"}
@@ -116,7 +116,7 @@ export class FileLib {
116
116
  ]);
117
117
  return this.analyzeMP3Buffer(buffer, { fileSize: stat.size });
118
118
  }
119
- static async analyzeAudioFile(filePath, format) {
119
+ static async analyzeMediaFile(filePath, format) {
120
120
  const [buffer, stat] = await Promise.all([
121
121
  fs.promises.readFile(filePath),
122
122
  fs.promises.stat(filePath)
@@ -128,9 +128,12 @@ export class FileLib {
128
128
  if (format !== undefined) {
129
129
  opts.format = format;
130
130
  }
131
- return this.analyzeAudioBuffer(buffer, opts);
131
+ return this.analyzeMediaBuffer(buffer, opts);
132
132
  }
133
- static analyzeAudioBuffer(buffer, opts = {}) {
133
+ static async analyzeAudioFile(filePath, format) {
134
+ return this.analyzeMediaFile(filePath, format);
135
+ }
136
+ static analyzeMediaBuffer(buffer, opts = {}) {
134
137
  let parser;
135
138
  if (opts.format) {
136
139
  parser = ParserFactory.getParser(opts.format);
@@ -150,6 +153,9 @@ export class FileLib {
150
153
  const analyzeOpts = opts.fileSize !== undefined ? { fileSize: opts.fileSize } : {};
151
154
  return parser.analyze(buffer, analyzeOpts);
152
155
  }
156
+ static analyzeAudioBuffer(buffer, opts = {}) {
157
+ return this.analyzeMediaBuffer(buffer, opts);
158
+ }
153
159
  static calculateFrameLength(frame) {
154
160
  if (frame.layer === 1) {
155
161
  return Math.floor(((12 * frame.bitrate * 1000) / frame.sampleRate + frame.padding) * 4);
@@ -1 +1 @@
1
- {"version":3,"file":"FileLib.js","sourceRoot":"","sources":["../../src/Libs/FileLib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FileLib.js","sourceRoot":"","sources":["../../src/Libs/FileLib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAuBzD,MAAM,OAAO,OAAO;IA4BlB,MAAM,CAAC,kBAAkB,CAAC,MAAc;QACtC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAKD,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,SAAiB;QACrD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAKD,MAAM,CAAC,gBAAgB,CAAC,MAAc,EAAE,OAA8B,EAAE;QACtE,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC;QAE5C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,IAAI;gBACJ,QAAQ,EAAE,CAAC;gBACX,aAAa,EAAE,CAAC;gBAChB,MAAM,EAAE,EAAE;aACX,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAmB,EAAE,CAAC;QAClC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAExE,IAAI,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;QACjC,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,UAA8B,CAAC;QACnC,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,OAAO,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;gBACtC,MAAM,EAAE,CAAC;gBACT,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;YAE7C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,EAAE,CAAC;gBACT,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAEtD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC,2CAA2C,MAAM,EAAE,CAAC,CAAC;gBACnE,MAAM,EAAE,CAAC;gBACT,SAAS;YACX,CAAC;YAGD,IAAI,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBACzC,QAAQ,CAAC,IAAI,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;gBACrD,MAAM;YACR,CAAC;YAED,UAAU,GAAG,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;YAE7C,MAAM,aAAa,GAAG,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC;YAEjE,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,UAAU;gBACjB,MAAM;gBACN,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,aAAa;gBACvB,OAAO,EAAE,MAAM,CAAC,eAAe;gBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB,CAAC,CAAC;YAEH,UAAU,EAAE,CAAC;YACb,aAAa,IAAI,aAAa,CAAC;YAC/B,eAAe,IAAI,WAAW,CAAC;YAC/B,MAAM,IAAI,WAAW,CAAC;QACxB,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;YAC9E,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC;gBAC5C,aAAa,EAAE,WAAW;gBAC1B,MAAM,EAAE,EAAE;aACX,CAAC;YAEF,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpB,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC/B,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,aAAa,CAAC;QAC/B,MAAM,cAAc,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,MAAM,QAAQ,GAAgB;YAC5B,IAAI;YACJ,QAAQ;YACR,aAAa,EAAE,eAAe,IAAI,WAAW;YAC7C,MAAM;SACP,CAAC;QAEF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,CAAC;QAED,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,QAAQ,CAAC,cAAc,GAAG,cAAc,CAAC;QAC3C,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACzC,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACzC,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC/B,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAMD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC1C,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC9B,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;SAC3B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IAQD,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,MAAoB;QAClE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACvC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC9B,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;SAC3B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAiE;YACzE,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,QAAQ;SACT,CAAC;QAEF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAGD,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,MAAoB;QAClE,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAQD,MAAM,CAAC,kBAAkB,CACvB,MAAc,EACd,OAAuE,EAAE;QAEzE,IAAI,MAAM,CAAC;QAGX,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAGD,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,GAAG,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;QAGD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7C,CAAC;IAGD,MAAM,CAAC,kBAAkB,CACvB,MAAc,EACd,OAAuE,EAAE;QAEzE,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,KAAwB;QAC1D,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5F,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,MAAc;QACzC,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YACpE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC5C,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC,CAAC;QACxD,CAAC;QAGD,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC;YACtC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;gBACjE,SAAS,GAAG,GAAG,CAAC;gBAChB,QAAQ,GAAG,SAAS,CAAC;YACvB,CAAC;QACH,CAAC;QAED,OAAO;YACL,WAAW;YACX,SAAS;YACT,QAAQ;YACR,SAAS;SACV,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,KAAa;QAC1C,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC,KAAK,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEjC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;IACnD,CAAC;IAEO,MAAM,CAAC,gBAAgB,CAAC,MAAc;QAC5C,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC;QACzC,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC;QACvC,MAAM,YAAY,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC;QAC1C,MAAM,eAAe,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC;QAC7C,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAU,CAAC;QAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAE1C,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,EAAE,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC;QAEpE,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEhE,OAAO;YACL,OAAO;YACP,KAAK;YACL,OAAO;YACP,UAAU;YACV,OAAO;YACP,eAAe;SAChB,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,aAAa,CAAC,IAAY;QACvC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,IAAI;gBACP,OAAO,CAAC,CAAC;YACX,KAAK,IAAI;gBACP,OAAO,CAAC,CAAC;YACX,KAAK,IAAI;gBACP,OAAO,EAAE,CAAC;YACZ;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,WAAW,CAAC,IAAY;QACrC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,IAAI;gBACP,OAAO,CAAC,CAAC;YACX,KAAK,IAAI;gBACP,OAAO,CAAC,CAAC;YACX,KAAK,IAAI;gBACP,OAAO,CAAC,CAAC;YACX;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,kBAAkB,CAAC,OAAmB,EAAE,KAAgB;QACrE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,GAAG,CAAC;QACb,CAAC;QAED,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IACpC,CAAC;;AAlYuB;;;;WAAiE;QACvF,CAAC,EAAE;YACD,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACzE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACtE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SACtE;QACD,CAAC,EAAE;YACD,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACtE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SAClE;QACD,EAAE,EAAE;YACF,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACtE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACjE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SAClE;KACF;GAAC;AAEsB;;;;WAAkD;QACxE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;QACxB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;QACxB,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;KACzB;GAAC"}
@@ -1,7 +1,7 @@
1
- import { AudioFormat } from '../Parsers/IAudioParser';
1
+ import { MediaFormat } from '../Parsers/IMediaParser';
2
2
  export declare class FormatDetector {
3
- static detectFormat(buffer: Buffer): AudioFormat | null;
4
- static detectFormatFromExtension(filePath: string): AudioFormat | null;
3
+ static detectFormat(buffer: Buffer): MediaFormat | null;
4
+ static detectFormatFromExtension(filePath: string): MediaFormat | null;
5
5
  static getSupportedExtensions(): string[];
6
6
  static isSupportedExtension(filePath: string): boolean;
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FormatDetector.d.ts","sourceRoot":"","sources":["../../src/Libs/FormatDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,qBAAa,cAAc;IAMzB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAoDvD,MAAM,CAAC,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IA0BtE,MAAM,CAAC,sBAAsB,IAAI,MAAM,EAAE;IAOzC,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAIvD"}
1
+ {"version":3,"file":"FormatDetector.d.ts","sourceRoot":"","sources":["../../src/Libs/FormatDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,qBAAa,cAAc;IAMzB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IA8EvD,MAAM,CAAC,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAgCtE,MAAM,CAAC,sBAAsB,IAAI,MAAM,EAAE;IAOzC,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAIvD"}
@@ -6,8 +6,18 @@ export class FormatDetector {
6
6
  if (buffer.toString('ascii', 0, 3) === 'ID3') {
7
7
  return 'mp3';
8
8
  }
9
- if (buffer.length >= 2 && buffer[0] === 0xff && (buffer[1] & 0xe0) === 0xe0) {
10
- return 'mp3';
9
+ if (buffer.length >= 2 && buffer[0] === 0xff) {
10
+ const secondByte = buffer[1];
11
+ if ((secondByte & 0xf6) === 0xf0) {
12
+ return 'aac';
13
+ }
14
+ if ((secondByte & 0xe0) === 0xe0) {
15
+ const versionBits = (secondByte >> 3) & 0x3;
16
+ const layerBits = (secondByte >> 1) & 0x3;
17
+ if (versionBits !== 0x1 && layerBits !== 0x0) {
18
+ return 'mp3';
19
+ }
20
+ }
11
21
  }
12
22
  if (buffer.toString('ascii', 0, 4) === 'fLaC') {
13
23
  return 'flac';
@@ -22,12 +32,20 @@ export class FormatDetector {
22
32
  }
23
33
  if (buffer.length >= 12 && buffer.toString('ascii', 4, 8) === 'ftyp') {
24
34
  const brand = buffer.toString('ascii', 8, 12);
25
- if (brand === 'M4A ' || brand === 'M4B ' || brand === 'mp42' || brand === 'isom') {
35
+ if (brand === 'M4A ' || brand === 'M4B ') {
26
36
  return 'm4a';
27
37
  }
28
- }
29
- if (buffer.length >= 2 && buffer[0] === 0xff && (buffer[1] & 0xf6) === 0xf0) {
30
- return 'aac';
38
+ if (brand === 'qt ') {
39
+ return 'mov';
40
+ }
41
+ if (brand.startsWith('M4V')) {
42
+ return 'm4v';
43
+ }
44
+ if (brand === 'mp42' || brand === 'isom' || brand === 'mp41' ||
45
+ brand === 'avc1' || brand === 'iso2' || brand === 'iso5' || brand === 'iso6') {
46
+ return 'mp4';
47
+ }
48
+ return 'mp4';
31
49
  }
32
50
  return null;
33
51
  }
@@ -48,12 +66,18 @@ export class FormatDetector {
48
66
  return 'flac';
49
67
  case 'wav':
50
68
  return 'wav';
69
+ case 'mp4':
70
+ return 'mp4';
71
+ case 'mov':
72
+ return 'mov';
73
+ case 'm4v':
74
+ return 'm4v';
51
75
  default:
52
76
  return null;
53
77
  }
54
78
  }
55
79
  static getSupportedExtensions() {
56
- return ['.mp3', '.aac', '.m4a', '.m4b', '.ogg', '.oga', '.flac', '.wav'];
80
+ return ['.mp3', '.aac', '.m4a', '.m4b', '.ogg', '.oga', '.flac', '.wav', '.mp4', '.mov', '.m4v'];
57
81
  }
58
82
  static isSupportedExtension(filePath) {
59
83
  const ext = '.' + filePath.toLowerCase().split('.').pop();