← Documentation

Les interviews

Une interview est une conversation avec un témoin. Le dossier garde ce qu'elle a établi, et peut garder sa transcription.

Un enquêteur s'arrête rarement au premier compte rendu d'un témoin. Il revient vers lui : pour fixer une valeur, demander ce qui n'a pas été dit, vérifier ce qui ne colle pas. Cette conversation est une interview, et un dossier peut la garder à côté des comptes rendus dont elle parle.

Une interview est une conversation menée avec un ou plusieurs témoins du dossier, par une ou plusieurs personnes (un enquêteur, une association), à un moment donné et par un certain moyen : face à face, téléphone, visioconférence, chat, mail ou courrier. Ce que le dossier en garde, c'est ce qu'elle a établi (une courte description, dans autant de langues qu'on veut) et, quand il y en a une, sa transcription : qui a dit quoi, et quand. La transcription est ce à quoi un lecteur peut confronter la description.

Plusieurs enquêteurs, plusieurs témoins#

Une interview peut avoir autant de locuteurs qu'on veut. by liste chaque enquêteur et interviewOf chaque observation avec laquelle elle a eu lieu ; dans le fichier, le premier enquêteur est interviewer, le suivant interviewer2, et de même witness, witness2… L'éditeur les garde en accord avec l'événement.

Sa place dans le dossier#

Un dossier contient des événements. Une interview en est un, et elle renvoie à l'observation du témoin avec qui elle a eu lieu (aux observations, quand plusieurs témoins ont été interrogés ensemble). Le renvoi va dans les deux sens : un passage de la transcription peut dire de quel moment de l'observation il parle, et l'observation liste alors, à ce moment, les passages qui la racontent. Rien d'une interview n'est rejoué : l'observation est ce qu'on rejoue, l'interview est ce qui explique ses valeurs.

Un tour peut dire de quel moment de l'observation il parle : "refs": [{ "at": 0.5 }], en secondes depuis le début de l'observation. sighting nomme l'observation quand l'interview en concerne plusieurs, et range ([de, à] en caractères de text) la partie du tour concernée. Dans l'éditeur, un tour avec une référence a un bouton qui montre l'observation à ce moment, et l'observation liste, dessous, les passages qui la racontent (« Relaté dans … »), chacun un lien en retour vers le tour.

Retirer des passages#

Une transcription publiée peut contenir moins que ce qui a été enregistré : la vie privée, un nom, un lieu exact. Ce qui est retiré garde sa place (locuteur et temps) et dit pourquoi dans reason, pour qu'un lecteur voie un trou et sa raison plutôt qu'une coupe silencieuse. Quand seul un détail part, utilisez parts : la réponse à « y a-t-il des éclairages dans le parc ? » reste, les rues qui identifieraient le lieu s'en vont.

Qui l'a approuvée#

Une transcription est relue quand chaque locuteur l'a approuvée. proofreading donne à chaque locuteur un status : pending (pas demandé, ou sans réponse), approved, ou covered. covered vaut pour un fichier qui contient moins que ce que le locuteur a déjà approuvé (passages retirés, rien d'ajouté) : l'approbation antérieure du tout suffit, et coveredBy nomme cette version plus complète. Un locuteur qui n'est pas listé n'a pas approuvé.

Dans l'éditeur d'interview#

Résumé : les témoins, le moyen, la date, les enquêteurs et ce que l'interview a établi.
Résumé : les témoins, le moyen, la date, les enquêteurs et ce que l'interview a établi.
Échanges : l'interview comme un dialogue, un tour qui raconte un moment de l'observation avec son lien.
Échanges : l'interview comme un dialogue, un tour qui raconte un moment de l'observation avec son lien.
Fichier : la transcription en texte, complétée d'après son schéma, à charger depuis un fichier et à sauver.
Fichier : la transcription en texte, complétée d'après son schéma, à charger depuis un fichier et à sauver.

<rr0-interview-editor> a trois groupes : le Résumé (titre, témoins, moyen, date, enquêteurs, description), les Échanges (l'interview lue comme un dialogue : qui a dit quoi, le temps de chaque tour en infobulle, les passages retirés noircis avec leur raison, qui n'a pas encore approuvé) et le Fichier (la transcription en texte, complétée d'après son schéma, à charger et à sauver). C'est un morceau à part, chargé seulement quand un dossier contient une interview.

Importer une transcription qui n'est pas dans notre format#

La plupart des transcriptions viennent d'ailleurs. Dans le groupe Fichier, « Charger un fichier » lit, en plus du JSON :

  • WebVTT et SRT, tels qu'un outil d'enregistrement ou un éditeur de sous-titres les écrit : les temps sont gardés, le locuteur est la balise <v Nom> ou un Nom : avant le texte ;
  • du texte ou du Markdown avec un nom avant chaque tour : Nom : …, [00:12:34] Nom : …, Nom (00:12:34) : …, Q : / R : ou Q. / A. ; une ligne sans nom prolonge le tour précédent ;
  • de simples paragraphes : un tour chacun, sans locuteur ni temps.

Les noms trouvés sont rapprochés de ceux de l'interview : un nom qui est parmi ceux qui l'ont menée est un enquêteur, un nom qui est un témoin du dossier est ce témoin. Sinon, le premier à parler est l'enquêteur et les autres sont des témoins ; Q interroge toujours et R ou A répond toujours. Tous sont en attente d'approbation (pending), et la note dit de quel fichier cela vient.

Il devine, et le dit : ce qu'il rate se corrige dans le groupe Fichier. Les fichiers de traitement de texte et les PDF ne sont pas lus : enregistrez-les d'abord en texte. Un deux-points dans une phrase n'est pas pris pour un locuteur tant qu'un nom ne revient pas assez souvent.

Partie technique : les fichiers#

Ce qui suit est pour qui écrit ces fichiers à la main, les génère ou les lit en code. Dans l'éditeur, rien de cela n'a besoin d'être connu.

L'événement dans le dossier#

Dans case.json, une interview est un événement dont l'eventType vaut "interview".

ChampSignification
idCe par quoi d'autres éléments la désignent
timeQuand elle a eu lieu, comme le dossier écrit une date
titleSon nom, dit dans autant de langues qu'on veut
summaryCe qu'elle a établi, de la même façon
mediumin-person, phone, video, chat, email, letter ou other
byQui l'a menée : un agent, ou plusieurs ({ "people": "…" } ou { "org": "…" })
interviewOfL'id de l'observation avec laquelle elle a eu lieu, ou une liste quand il y avait plusieurs témoins
urlLe fichier de transcription, s'il y en a un, relatif au dossier

Le fichier de transcription#

Un fichier JSON simple, dont interview.schema.json est le schéma. Il contient tout ce que l'événement dit de l'interview (le résumé et le fichier restent identiques, quel que soit celui qu'on modifie) ET ce qui a été dit.

ChampSignification
version, id, language1 ; l'id de l'interview ; la langue dans laquelle elle s'est tenue
title, time, medium, by, interviewOf, summaryLes mêmes que ceux de l'événement
speakersQui parle, sous un id de votre choix : { role, by?, title?, of? }. role vaut interviewer ou witness ; by est l'agent de l'enquêteur ; title comment on appelle un témoin (ses initiales s'il n'est pas nommé) et of l'observation qu'il a donnée
transcriptionComment le texte a été obtenu : method (automatic ou manual), engine, et une note libre
proofreadingQui l'a approuvée, par locuteur (voir plus bas)
anonymizationCe qui a été remplacé (replaced) et ce qui le remplace (marker)
segmentsLes tours de parole, dans l'ordre

Un tour de parole

Chaque entrée de segments est un tour.

ChampSignification
speakerUne clé de speakers
start, endSecondes depuis le début de l'enregistrement, tous deux facultatifs : une transcription tapée à la main n'en a pas, et un tour sans temps n'est pas dans les sous-titres
textCe qui a été dit, en texte brut ou en HTML (un lien, un titre en italique, un mot étranger dans sa langue : ce qu'écrirait une page qui le publie), échappé comme toute chaîne JSON. Le format dit qui parle et quand ; le reste revient au HTML
redacted{ reason } : le tour entier a été retiré du fichier publié. Il n'a alors pas de text
partsÀ la place de text, quand seul un passage a été retiré : une liste de { text } et de { redacted }, dans l'ordre
refsLes moments de l'observation que ce tour raconte (voir « Liens avec l'observation »)

Chaque extrait ci-dessous est en lecture seule, et chacun connaît le format : placez le curseur dans un objet et faites Ctrl+Espace (⌥+I sur Mac) pour lister toutes les clés qui pourraient y figurer, avec ce que le modèle dit de chacune.

Un exemple

{
  "version": 1,
  "id": "interview-qb-1",
  "language": "fr",
  "title": { "fr": "Entretien avec Q. B." },
  "time": "2026-10-13 21:27",
  "medium": "video",
  "by": [{ "people": "BeauJerome" }],
  "interviewOf": "qb",
  "speakers": {
    "interviewer": { "role": "interviewer", "by": { "people": "BeauJerome" } },
    "witness": { "role": "witness", "title": "Q. B.", "of": "qb" }
  },
  "transcription": { "method": "automatic", "engine": "whisper.cpp large-v3-turbo" },
  "proofreading": { "interviewer": { "status": "approved" }, "witness": { "status": "pending" } },
  "segments": [
    { "speaker": "interviewer", "start": 0, "end": 4.2, "text": "Où étiez-vous ?" },
    { "speaker": "witness", "start": 5, "end": 9, "text": "Dans le parc.", "refs": [{ "at": 0.5 }] },
    { "speaker": "witness", "start": 10, "end": 18, "parts": [
      { "text": "Il n'y en a pas." },
      { "redacted": { "reason": { "fr": "Lieu précis" } } }
    ] },
    { "speaker": "interviewer", "start": 20, "end": 40, "redacted": { "reason": { "fr": "Vie privée" } } }
  ]
}

En code#

@rr0/data lit et écrit les mêmes fichiers : RR0Interview.fromEventJson / toEventJson pour l'événement, fromFileJson / toFileJson pour le fichier, et proofread dit si tous ont approuvé. Dans UFO@home, InterviewFile.toVtt fait des sous-titres d'une transcription, InterviewFile.passagesAbout liste les tours qui racontent une observation, et InterviewImport.parse lit un fichier étranger.

<rr0-interview>

Une interview lue comme un dialogue : qui a dit quoi, tel que son HTML le dit, les passages retirés en barres qui disent pourquoi, l'heure de chaque tour au survol, et les passages qui racontent un moment de l'observation en boutons qui y mènent. Il dessine dans la page elle-même, pas dans une racine fantôme : les styles de la page atteignent le texte et ses liens.

<script src="https://ufoathome.org/lib/rr0-interview.mjs" type="module"></script>
<rr0-sighting id="player" src="case.json"></rr0-sighting>
<rr0-interview src="interview.json" player="player"></rr0-interview>

Un module à part, léger : il contient le dialogue et rien de la scène ni des éditeurs.

MembreGenreCe qu'il fait
srcattributLe fichier de l'interview, relatif à la page. Ses liens sont relatifs à lui.
playerattributL'id d'un <rr0-sighting> de la page : un passage suivi jusqu'à son moment y montre l'observation, à ce moment.
interviewpropriétéL'interview montrée, donnée directement au lieu d'être lue.
documentUrlpropriétéCe à quoi les liens d'une interview donnée directement sont relatifs.
revealSegment(index)méthodeMontre ce tour et où il est.
interviewseekévénementEnvoyé, en remontant, quand un lecteur suit un tour jusqu'au moment de l'observation qu'il raconte : detail vaut { sighting, at }.

<rr0-interview-editor>

L'éditeur d'une interview d'un dossier : son résumé, ses échanges et son fichier de transcription. L'éditeur de dossier le montre à la place de l'éditeur d'enregistrement quand une interview est choisie.

const interview = document.createElement("rr0-interview-editor")
interview.documentUrl = "https://example.org/cases/saint-lo/case.json"
interview.witnesses = [{ id: "qb", label: "Q. B." }]
interview.event = { type: "event", eventType: "interview", interviewOf: "qb" }
interview.addEventListener("interviewchange", event => console.log(event.detail.field))

Pas un module à part : celui de l'éditeur de dossier le charge, et le définit, la première fois qu'une interview est montrée, puisque la plupart des dossiers n'en ont pas.

MembreGenreCe qu'il fait
eventpropriétéL'événement du dossier qui est l'interview, modifié en place.
witnessespropriétéLes observateurs avec qui elle a pu avoir lieu, [{ id, label }] : une case chacun, une au moins cochée.
documentUrlpropriétéCe à quoi l'url de la transcription est relative : l'adresse du dossier.
transcriptTextpropriétéLa transcription en texte, une fois modifiée ou chargée ; indéfinie avant, quand elle est lue à l'url de l'événement.
readonlyattributNe fait que montrer l'interview.
revealSegment(index)méthodeOuvre le groupe Échanges à ce tour et montre où il est.
interviewchangeévénementEnvoyé, en remontant, à chaque modification : detail vaut { field, event, text? }, le texte de la transcription étant dans text.
interviewseekévénementEnvoyé, en remontant, quand un lecteur suit un tour jusqu'au moment de l'observation qu'il raconte : detail vaut { sighting, at }, at en secondes depuis le début de l'observation.