-
Notifications
You must be signed in to change notification settings - Fork 1
Web Setup
hAudiotagger supports web via WebAssembly. This page covers the required configuration for web deployment.
- Flutter 3.0.0+
- Dart SDK 3.6.0+
- Cross-origin isolation enabled
WebAssembly shared memory requires cross-origin isolation. Your host page must send these headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Without these headers, the WASM module will fail to load with a shared memory error.
flutter run -d chrome \
--web-header=Cross-Origin-Opener-Policy=same-origin \
--web-header=Cross-Origin-Embedder-Policy=require-corpflutter build webThen serve with a server that sends the required headers.
Create netlify.toml:
[[headers]]
for = "/*"
[headers.values]
Cross-Origin-Opener-Policy = "same-origin"
Cross-Origin-Embedder-Policy = "require-corp"Create vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
{ "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }
]
}
]
}Create or edit .htaccess:
<IfModule mod_headers.c>
Header set Cross-Origin-Opener-Policy "same-origin"
Header set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>location / {
add_header Cross-Origin-Opener-Policy "same-origin";
add_header Cross-Origin-Embedder-Policy "require-corp";
}GitHub Pages doesn't support custom headers. Use a proxy service like Cloudflare Workers or Netlify for production.
For local testing, use the Flutter run command with headers.
On the web, file path APIs are not available. Use the *FromBytes variants:
| Native API | Web API |
|---|---|
read(path) |
readFromBytes(bytes) |
write(path, tag) |
writeToBytes(bytes, tag) |
update(path, changes) |
updateFromBytes(bytes, changes) |
getChapters(path) |
getChaptersFromBytes(bytes) |
getExtended(path) |
getExtendedFromBytes(bytes) |
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:haudiotagger/haudiotagger.dart';
class WebAudioMetadata extends StatefulWidget {
@override
State<WebAudioMetadata> createState() => _WebAudioMetadataState();
}
class _WebAudioMetadataState extends State<WebAudioMetadata> {
Tag? _tag;
Uint8List? _fileBytes;
Future<void> _pickFile() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.audio,
);
if (result != null && result.files.first.bytes != null) {
setState(() {
_fileBytes = result.files.first.bytes;
});
await _readMetadata();
}
}
Future<void> _readMetadata() async {
if (_fileBytes == null) return;
final tag = await Haudiotagger.readFromBytes(_fileBytes!);
setState(() {
_tag = tag;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Audio Metadata (Web)')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _pickFile,
child: Text('Pick Audio File'),
),
if (_tag != null) ...[
SizedBox(height: 20),
Text('Title: ${_tag!.title}'),
Text('Artist: ${_tag!.trackArtist}'),
Text('Album: ${_tag!.album}'),
],
],
),
),
);
}
}Cross-origin isolation is not enabled. Check that your server is sending the required headers.
Ensure you're using a production build (flutter build web) and serving the files from a proper web server, not file:// protocol.
WebAssembly runs single-threaded. For large batch operations, consider using the native platforms (Android, iOS, desktop) which support parallel processing via rayon.
Made with ❤️ and 🦀 by Hirdaya Shrestha