Corriger deux blocages du scan trouves en navigateur, et consigner les mesures reelles
Les deux defauts ont ete constates en executant reellement l'application, pas par relecture : 1. L'import du module JS partait en 404 en developpement. L'import map generee par Blazor reecrit « ./js/scanner-camera.js » vers un nom empreinte que l'API hote ne sert pas (UseStaticFiles ignore les points d'entree empreintes). Une chaine de requete sur le specifieur empeche la reecriture ; en publication rien n'est reecrit pour ce fichier, le comportement est donc identique dans les deux modes. 2. Les messages d'erreur camera etaient tous generiques. Une DOMException perd son « name » en traversant le pont JS vers C# : un refus de permission arrivait sous la forme « Permission denied undefined ». Le JS attrape donc l'erreur et renvoie un code de statut stable, que le C# traduit en message utile. CLAUDE.md est mis a jour avec les mesures reelles obtenues en WASM, qui manquaient : la performance de decodage (l'estimation de 5-10 ms/frame est confirmee, l'AOT reste inutile) et le surcout de payload, nettement superieur aux 192 Ko documentes une fois comptees les assemblies BCL que ZXing empeche le trimmer de retirer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -67,6 +67,14 @@
|
||||
|
||||
private enum Etat { Demarrage, Actif, Erreur }
|
||||
|
||||
// Le « ?m=1 » n'est pas cosmétique. En développement, l'import map généré par Blazor
|
||||
// fait pointer « ./js/scanner-camera.js » vers un nom empreinté que l'API hôte ne sert
|
||||
// pas (elle utilise UseStaticFiles, qui ignore les points d'entrée empreintés) : l'import
|
||||
// échoue en 404 et le scan ne démarre jamais. Une chaîne de requête empêche l'import map
|
||||
// de réécrire le chemin ; en publication, aucune réécriture n'est générée pour ce fichier,
|
||||
// donc le comportement est identique. Vérifié dans les deux modes.
|
||||
private const string CheminModule = "./js/scanner-camera.js?m=1";
|
||||
|
||||
// ~12 images/s : bien assez pour scanner, et deux fois moins de travail que 25 fps.
|
||||
private const int IntervalleMs = 80;
|
||||
|
||||
@@ -96,7 +104,7 @@
|
||||
|
||||
try
|
||||
{
|
||||
_module = await JS.InvokeAsync<IJSObjectReference>("import", "./js/scanner-camera.js");
|
||||
_module = await JS.InvokeAsync<IJSObjectReference>("import", CheminModule);
|
||||
|
||||
var diagnostic = await _module.InvokeAsync<string>("diagnostic");
|
||||
if (diagnostic != "ok")
|
||||
@@ -114,29 +122,32 @@
|
||||
return;
|
||||
}
|
||||
|
||||
await _module.InvokeVoidAsync("demarrer", _video);
|
||||
// On ne laisse jamais un écran noir sans explication : chaque code dit précisément
|
||||
// ce qui manque à l'utilisateur pour que le scan fonctionne.
|
||||
var statut = await _module.InvokeAsync<string>("demarrer", _video);
|
||||
if (statut != "ok")
|
||||
{
|
||||
Echouer(statut switch
|
||||
{
|
||||
"permission-refusee" =>
|
||||
"L'accès à la caméra a été refusé. Autorisez-le dans les réglages du navigateur, "
|
||||
+ "ou saisissez l'ISBN à la main.",
|
||||
"aucune-camera" =>
|
||||
"Aucune caméra utilisable n'a été trouvée sur cet appareil. Saisissez l'ISBN à la main.",
|
||||
"camera-occupee" =>
|
||||
"La caméra est déjà utilisée par une autre application. Fermez-la, ou saisissez l'ISBN à la main.",
|
||||
_ => $"La caméra n'a pas pu démarrer ({statut[(statut.IndexOf(':') + 1)..].Trim()}). "
|
||||
+ "Saisissez l'ISBN à la main.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_etat = Etat.Actif;
|
||||
StateHasChanged();
|
||||
|
||||
_boucle = new CancellationTokenSource();
|
||||
_ = BoucleAsync(_boucle.Token);
|
||||
}
|
||||
catch (JSException ex)
|
||||
{
|
||||
// On ne laisse jamais un écran noir sans explication : le nom de l'erreur DOM
|
||||
// dit précisément ce qui manque à l'utilisateur pour que ça marche.
|
||||
Echouer(NomErreurDom(ex.Message) switch
|
||||
{
|
||||
"NotAllowedError" or "SecurityError" =>
|
||||
"L'accès à la caméra a été refusé. Autorisez-le dans les réglages du navigateur, "
|
||||
+ "ou saisissez l'ISBN à la main.",
|
||||
"NotFoundError" or "DevicesNotFoundError" or "OverconstrainedError" =>
|
||||
"Aucune caméra utilisable n'a été trouvée sur cet appareil. Saisissez l'ISBN à la main.",
|
||||
"NotReadableError" or "TrackStartError" =>
|
||||
"La caméra est déjà utilisée par une autre application. Fermez-la, ou saisissez l'ISBN à la main.",
|
||||
_ => $"La caméra n'a pas pu démarrer ({ex.Message}). Saisissez l'ISBN à la main.",
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Echouer($"La caméra n'a pas pu démarrer ({ex.Message}). Saisissez l'ISBN à la main.");
|
||||
@@ -216,13 +227,6 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private static string NomErreurDom(string message)
|
||||
{
|
||||
// Blazor sérialise l'erreur DOM sous la forme "NotAllowedError: Permission denied".
|
||||
var separateur = message.IndexOf(':');
|
||||
return separateur > 0 ? message[..separateur].Trim() : message.Trim();
|
||||
}
|
||||
|
||||
private async Task ArreterCameraAsync()
|
||||
{
|
||||
_boucle?.Cancel();
|
||||
|
||||
Reference in New Issue
Block a user