logo

DOTE (Distributed Open Transcription Environment)

DOTE 2.0 Help Guide

DOTE JSON File Formats

Reference for every JSON file that DOTE reads and writes when loading or saving Projects and Transcripts.


Directory Layout

<ProjectName>/                   ← Project directory (ProjectPath)
  .project.json                  ← Project descriptor
  .media_clips.json              ← Project-level media clips
  .annotations.json              ← Annotations for media clips
  .tiers.json                    ← Clip tier definitions
  .dotebase_meta.json            ← DOTEbase project metadata
  <video/audio files>            ← Raw media assets

  <TranscriptName>/              ← Transcript subdirectory (TranscriptPath)
    transcript.txt               ← Plain-text transcript (not JSON)
    .transcript.json             ← Transcript descriptor (sync codes, settings, etc.)
    .media_meta.json             ← Media/viewport/cue metadata
    .transcript_clips.json       ← Transcript-level text-range clips
    .annotations.json            ← Annotations for transcript clips
    .dotebase_meta.json          ← DOTEbase transcript metadata
    .autosaves/                  ← Auto-backup snapshots

All filenames beginning with . are hidden on disk.


1. .project.json — Project Descriptor

Location: Project root directory

{
  // DOTE version that last wrote this file (semver string, e.g. "2.0.0-Beta-RC3")
  "projectDescVersion": "string",

  // Ordered list of media files registered to this project
  "projectMedia": [
    {
      // Base filename of the media file (relative to project directory)
      "filename": "string",

      // 0 = VideoFile, 1 = AudioFile
      "fileType": 0,

      // Playback volume in the range [0, 1]
      "volume": 1.0,

      // Whether this media file is muted
      "mute": false,

      // (Video only) Projection type: 0 = Regular2D, 1 = V360Equirect, 2 = AudioOnly
      "videoProjectionType": 0,

      // (360-video only) Projection method: 0 = Equirectangular, 1 = LambertAzimuthal, 2 = Dote
      "v360ProjectionMethod": 2,

      // Legacy field — absolute file path used in pre-2.0 files; ignored on write
      "filepath": "string | undefined"
    }
  ],

  // Legacy fields — kept for backwards compatibility, not actively used
  "videoName": null,             // string | null
  "videoProjection": 0,          // VideoProjectionType enum value
  "videoDisplayProjection": 2    // V360ProjectionMethod enum value
}

2. .transcript.json — Transcript Descriptor

Location: Transcript subdirectory

{
  // DOTE version that last wrote this file
  "doteVersion": "string",

  // Font size for the Monaco code editor.
  // kind 0 = use global settings default; kind 1 = overridden per-transcript
  "fontSize": {
    "kind": 0,           // 0 = Default, 1 = Overridden
    "defaultValue": 12,  // Used when kind = Default
    "value": 14          // Used when kind = Overridden (field absent when kind = Default)
  },

  // Width of the speaker-name column (in characters)
  "nameColumnWidth": {
    "kind": 0,
    "defaultValue": 10
  },

  // Whether the right-margin guide line is shown
  "rightMarginVisible": {
    "kind": 0,
    "defaultValue": false
  },

  // Column position of the right-margin guide (character offset)
  "defaultRightMarginPosition": {
    "kind": 0,
    "defaultValue": 70
  },

  // Suppress "missing overlap-end" syntax errors for this transcript
  "ignoreMissingOverlapEndErrors": {
    "kind": 0,
    "defaultValue": false
  },

  // Transcript notation convention: 0 = Jefferson, 1 = Mondada
  "transcriptConventions": 0,

  // Sync codes — map media timecodes to transcript line numbers
  "timeCodes": [
    {
      // Playback time in seconds (undefined only in very old pre-V1.0.0 files)
      "_time": 12.5,

      // 1-based line number in transcript.txt this sync code is attached to
      "_lineNumber": 10,

      // (V2.0.0+) Optional time span covering the associated transcript line
      "_timeRange": {
        "start": 12.5,   // seconds
        "end": 15.3      // seconds
      },

      // Legacy pre-V1.0.0 field: virtual frame number (30fps), superseded by _time
      "_virtualFrameNumber": 375
    }
  ],

  // User-drawn underline decorations in the editor (1-based line/column)
  "userUnderlines": [
    {
      "startLineNumber": 5,
      "startColumn": 1,
      "endLineNumber": 5,
      "endColumn": 20
    }
  ],

  // Language subtier tag strings that are auto-added to new clips
  "autoAddLangSubtiers": ["string"],

  // Gloss subtier tag strings that are auto-added to new clips
  "autoAddGlossSubtiers": ["string"],

  // Per-speaker action subtier configuration
  "actionSubtierProps": [
    {
      "speaker": "string",      // Speaker name this rule applies to
      "subtier": "string",      // Subtier label
      "autoComplete": true,     // Whether subtier is auto-completed on Enter
      "symbol": "string"        // Symbol character used for this action tier
    }
  ]
}

3. .media_meta.json — Media & Viewport Metadata

Location: Transcript subdirectory

{
  // Whether annotation decorations are visible in the editor
  "showAnnotations": true,

  // Whether syntax-warning highlights are shown
  "showWarnings": true,

  // Whether syntax-error highlights are shown
  "showErrors": true,

  // Whether the current sync-code block is highlighted
  "showCurrentTc": false,

  // Legacy DOTE 1.x field — secondary video panel visibility; not used in 2.0
  "secondaryViewVisible": false,

  // Legacy DOTE 1.x field — primary 360 projection method
  // 0 = Equirectangular, 1 = LambertAzimuthal, 2 = Dote
  "mainVideoDisplayProjection": 2,

  // Legacy DOTE 1.x field — secondary 360 projection method
  "secondaryVideoDisplayProjection": 2,

  // Total known duration of the primary media file (seconds)
  "duration": 0.0,

  // Last playback head position (seconds)
  "currentPlaybackTime": 0.0,

  // Selected time range on the waveform timeline [startSec, endSec]
  "currentSelectionRange": [0.0, 0.0],

  // Per-waveform-panel timeline view ranges, keyed by panel instanceID
  "timelineViewRanges": {
    "1": [0.0, 60.0]   // instanceID → [startSec, endSec]
  },

  // Filenames of media files currently active in this transcript
  "activeMediaFilenames": ["string"],

  // Per-display viewport state (one entry per video/waveform panel)
  "viewportSettings": [
    {
      // Unique panel display ID (e.g. "1", "2", or a waveform instanceID)
      "displayID": "string",

      // Filename of the media file currently shown in this panel
      "currentMediaFilename": "string",

      // (Optional) displayID of another panel whose media assignment this mirrors
      "followExisting": "string | undefined",

      // Camera view parameters saved per media file (360-video only)
      "viewControlByVideo": [
        {
          "mediaFilename": "string",
          "viewParameters": {
            "fovY": 1.5708,       // Vertical field of view in radians
            "rotRight": 0.0,      // Camera pitch (rotation around right axis), radians
            "rotUp": 0.0          // Camera yaw (rotation around up axis), radians
          }
        }
      ],

      // View interaction mode: 0 = FollowCues, 1 = SaveView, 2 = FreeLook
      "viewMode": 1,

      // Subtitle overlay settings for this panel
      "subtitleSettings": {
        "srtFilename": null,        // Filename of .srt file in project dir (null = none)
        "fontFamily": "Courier New",
        "fontSize": 8,             // % of canvas height
        "fontColor": "#FFFFFF",
        "showOutline": true,
        "outlineColor": "#898989",
        "outlineWidth": 1,         // % of canvas height
        "showGlow": true,
        "glowColor": "#464646",
        "glowBlur": 4,             // % of canvas height
        "verticalPosition": 85,    // % from top (0 = top, 100 = bottom)
        "maxLineLength": 35,       // max chars per line before wrapping (null = none)
        "enabled": false,
        "minDisplayDuration": 1,   // seconds a subtitle stays visible at minimum
        "allowOverlap": true       // permit stacked/overlapping subtitles
      }
    }
  ],

  // Video cue timeline markers (camera angles / transition points)
  "videoCues": [
    {
      // Filename of the video file this cue references
      "videoFilename": "string",

      // Cue trigger time (seconds)
      "time": 10.0,

      // Transition style: 0 = JumpCut, 1 = Smooth
      "videoTransitionType": 0,

      // Duration of smooth transition (seconds); only present when type = Smooth
      "transitionTime": 2.0,

      // Camera angle at this cue (360-video only)
      "rotUp": 0.0,       // radians
      "rotRight": 0.0,    // radians
      "fovY": 1.5708      // radians
    }
  ]
}

4. .media_clips.json — Project Media Clips

Location: Project root directory

Top-level value is a JSON array. Each element represents one media clip (a time-span selection on the media timeline).

[
  {
    // Unix timestamp (ms) of the last modification
    "lastUpdated": "number",

    // Stable UUID for this clip (uuid v4 string)
    "uuid": "string",

    // Absolute path of the project or transcript that originally created this clip
    "originalParentPath": "string",

    // UUID of a linked transcript clip ("" if none)
    "linkedClipID": "string",

    // Tag names applied to this clip
    "tagNames": ["string"],

    // Names of tiers (sub-categories) this clip belongs to
    "tierNames": ["string"],

    // Filename of the media file this time-span references
    "referenceMediaFilename": "string",

    // The selected time range on the media timeline
    "timeSpan": {
      "lastUpdated": "number",      // Unix ms
      "startTime": 10.5,            // seconds
      "endTime": 15.2,              // seconds (optional — absent for point clips)
      "approximate": false          // true if the boundaries are approximate
    }
  }
]

5. .transcript_clips.json — Transcript Text Clips

Location: Transcript subdirectory

Top-level value is a JSON array. Each element represents one transcript clip (a text-range selection in the editor).

[
  {
    // Unix timestamp (ms) of the last modification
    "lastUpdated": "number",

    // Stable UUID for this clip (uuid v4 string)
    "uuid": "string",

    // Absolute path of the transcript that originally created this clip
    "originalParentPath": "string",

    // UUID of a linked media clip ("" if none)
    "linkedClipID": "string",

    // Tag names applied to this clip
    "tagNames": ["string"],

    // Selected region in the transcript editor (1-based line and column numbers)
    "textRange": {
      "startLineNumber": 5,
      "startColumn": 1,
      "endLineNumber": 6,
      "endColumn": 12
    }
  }
]

6. .annotations.json — Clip Annotations

Location: Project root directory (for media clips) and transcript subdirectory (for transcript clips) TypeScript type: AnnotationData[] (src/types-and-interfaces/clips-datatypes.ts)

Top-level value is a JSON array. Each annotation is associated with exactly one clip via clipUUID.

[
  {
    // Unix timestamp (ms) of the last modification
    "lastUpdated": "number",

    // Stable UUID for this annotation (uuid v4 string)
    "UUID": "string",

    // Absolute path of the project/transcript that originally created this annotation
    "originalParentPath": "string",

    // UUID of the clip this annotation is attached to
    "clipUUID": "string",

    // Free-text researcher comment
    "comments": "string",

    // User-defined key/value metadata fields
    "userFields": [
      {
        "lastUpdated": "number",      // Unix ms
        "name": "string",             // Field name (e.g. "Name", "Code")
        "value": "string",            // Field value
        "visibleInClip": true         // Whether this field is shown on the clip card
      }
    ],

    // Visual display properties — shape depends on the 'type' discriminant

    // --- Variant A: No visual (type = 0) ---
    "ui": {
      "type": 0,          // VDPtype.Undefined
      "icon": "string",   // (optional) named icon from ClipIconNames
      "emoji": "string"   // (optional) emoji character
    },

    // --- Variant B: Transcript editor decoration (type = 1) ---
    "ui": {
      "type": 1,                          // VDPtype.Transcript
      "icon": "string",                   // optional
      "emoji": "string",                  // optional
      "useAnnotationHighlight": true,
      // Style of the rough-notation highlight drawn around the text range
      // Allowed values: "underline" | "box" | "circle" | "highlight" | "strike-through" | "crossed-off" | "bracket"
      "annotationHighlightType": "box",
      "highlightColour": "rgb(68, 83, 252)",
      "highlightColourPresetName": "string",  // optional preset name
      "useBackgroundColour": false,
      "backgroundColour": "rgba(68, 83, 252, 0.15)",
      "backgroundColourPresetName": "string", // optional
      // Low-level Monaco editor decoration options (see Monaco IModelDecorationOptions)
      "monacoDecorationOptions": { "zIndex": 2 },
      "inlineClass": "string"             // optional CSS class applied inline
    },

    // --- Variant C: Media waveform decoration (type = 2) ---
    "ui": {
      "type": 2,                          // VDPtype.Media
      "icon": "string",                   // optional
      "emoji": "string",                  // optional
      "useBackgroundColour": false,
      "backgroundColour": "rgba(68, 83, 252, 0.15)",
      "backgroundColourPresetName": "string" // optional
    }
  }
]

7. .tiers.json — Clip Tier Definitions

Location: Project root directory

Top-level value is a JSON array. Tiers are named sub-categories that media clips can belong to.

[
  {
    // Display name of the tier
    "name": "string",

    // Whether this tier is currently visible in the UI
    "visible": true,

    // Optional researcher description of the tier's purpose
    "description": "string",

    // Visual styling for this tier
    "ui": {
      // Hex colour string (e.g. "#FF5733") or null/undefined for no colour
      "colour": "string | null",

      // (Optional) name of a colour preset
      "colourPresetName": "string"
    }
  }
]

8. .dotebase_meta.json — DOTEbase Metadata (Project)

Location: Project root directory

{
  // Absolute filesystem path of the project when this file was first created.
  // Used to detect whether the project folder has been moved or copied.
  "pathOnCreation": "string",

  // Explicit sort order for the clip panel — array of UUIDs covering both
  // media clips and transcript clips. undefined/null means default sort order.
  "clipSortOrder": ["uuid-string-1", "uuid-string-2"]
}

9. .dotebase_meta.json — DOTEbase Metadata (Transcript)

Location: Transcript subdirectory

The same filename is used in both the project root and each transcript subdirectory but contains different data.

{
  // Whether annotation decorations are visible in the transcript editor
  "showAnnotations": true,

  // Whether syntax-warning highlights are shown in the editor
  "showWarnings": false,

  // Whether syntax-error highlights are shown in the editor
  "showErrors": false,

  // Whether the current sync-code line block is highlighted
  "showCurrentSyncCodes": false,

  // Viewport state for each panel associated with this transcript
  // Uses the same ViewportSettings structure as .media_meta.json viewportSettings
  "viewportSettings": [
    {
      "displayID": "string",
      "currentMediaFilename": "string",
      "followExisting": "string | undefined",
      "viewControlByVideo": [
        {
          "mediaFilename": "string",
          "viewParameters": { "fovY": 1.5708, "rotRight": 0.0, "rotUp": 0.0 }
        }
      ],
      "viewMode": 1,
      "subtitleSettings": { /* see .media_meta.json § subtitleSettings */ }
    }
  ]
}

Shared Sub-Types

OverridableAttribute

Used in .transcript.json for fontSize, nameColumnWidth, defaultRightMarginPosition. Each setting can either follow the global app preference or be overridden per-transcript.

// Variant A — use global settings default
{ "kind": 0, "defaultValue": 12 }

// Variant B — overridden per-transcript
{ "kind": 1, "value": 16, "defaultValue": 12 }
// kind: 0 = Default, 1 = Overridden

OverridableToggleAttribute

Same pattern as OverridableAttribute but with boolean values. Used for rightMarginVisible and ignoreMissingOverlapEndErrors.

{ "kind": 0, "defaultValue": false }
{ "kind": 1, "value": true, "defaultValue": false }

SyncCodeData

Element of timeCodes array in .transcript.json.

{
  "_time": 12.5,           // Timecode in seconds (undefined only in pre-V1.0.0 files)
  "_lineNumber": 10,       // 1-based line number in transcript.txt
  "_timeRange": {          // (V2.0.0+) Optional time span for the line
    "start": 12.5,         // seconds
    "end": 15.3            // seconds
  },
  // Legacy field present only in very old files created before V1.0.0:
  "_virtualFrameNumber": 375  // virtual frames at 30fps, superseded by _time
}

TextRange

Used in userUnderlines (.transcript.json) and textRange (.transcript_clips.json). All values are 1-based.

{
  "startLineNumber": 5,
  "startColumn": 1,
  "endLineNumber": 5,
  "endColumn": 20
}

TimeSpan

Used inside each entry in .media_clips.json.

{
  "lastUpdated": "number",      // Unix ms timestamp
  "startTime": 10.5,            // seconds
  "endTime": 15.2,              // seconds (absent for point-in-time clips)
  "approximate": false          // true if boundaries are estimates
}

ViewportSettings

Shared by viewportSettings arrays in both .media_meta.json and the transcript .dotebase_meta.json.

{
  "displayID": "string",             // Panel ID (e.g. "1" for primary video)
  "currentMediaFilename": "string",  // Media file currently loaded in this panel
  "followExisting": "string",        // (Optional) Mirror media from another displayID
  "viewControlByVideo": [            // Saved camera angles, keyed per media file
    {
      "mediaFilename": "string",
      "viewParameters": {
        "fovY": 1.5708,              // Vertical field of view, radians
        "rotRight": 0.0,             // Pitch, radians
        "rotUp": 0.0                 // Yaw, radians
      }
    }
  ],
  "viewMode": 1,                     // 0=FollowCues, 1=SaveView, 2=FreeLook
  "subtitleSettings": { /* SubtitleSettings — see .media_meta.json */ }
}