Index: src/services/AudioTranscoder.js
===================================================================
--- src/services/AudioTranscoder.js	(revision 2165b6d3d57ceaa8b5d1f70491868482149470cf)
+++ src/services/AudioTranscoder.js	(revision 7bc636b391c66ac399c33e54f7173a022c6a3cbd)
@@ -90,8 +90,6 @@
   const tmpPath = path.join(outputDir, `${outputBaseName}.transcoding-${process.pid}.mp3`);
 
-  let durationSec = null;
   try {
-    const r = await runFfmpeg({ inputPath, tmpPath, tags });
-    durationSec = r && r.durationSec != null ? r.durationSec : null;
+    await runFfmpeg({ inputPath, tmpPath, tags });
 
     // Verify the output is not zero bytes — ffmpeg sometimes "succeeds" but
@@ -126,5 +124,4 @@
       size: outStat.size,
       mimeType: 'audio/mpeg',
-      durationSec,   // whole seconds from ffmpeg's codecData (null if unknown)
     };
 
@@ -138,43 +135,4 @@
 
 /**
- * Rewrite the ID3 tags of an EXISTING mp3 without re-encoding (`-c copy`).
- * Used when editing track metadata (title/artist/album/credit/license) so that
- * ownership info travels with the file on download.
- * ffmpeg cannot edit in-place → write to tmp and atomically rename back.
- */
-export async function retagMp3({ filePath, tags = {} }) {
-  if (!filePath) throw new Error('retagMp3: filePath required');
-  await stat(filePath); // throws if file is missing
-  const dir = path.dirname(filePath);
-  const base = path.basename(filePath, path.extname(filePath));
-  const tmpPath = path.join(dir, `${base}.retag-${process.pid}.mp3`);
-  try {
-    await new Promise((resolve, reject) => {
-      const cmd = ffmpeg(filePath)
-        .audioCodec('copy')        // no re-encode → fast, no quality loss
-        .format('mp3')
-        .outputOptions('-id3v2_version', '3')
-        .outputOptions('-map_metadata', '-1')
-        .outputOptions('-vn');
-      if (tags.title)     cmd.outputOptions('-metadata', `title=${tags.title}`);
-      if (tags.artist)    cmd.outputOptions('-metadata', `artist=${tags.artist}`);
-      if (tags.album)     cmd.outputOptions('-metadata', `album=${tags.album}`);
-      if (tags.copyright) cmd.outputOptions('-metadata', `copyright=${tags.copyright}`);
-      if (tags.comment)   cmd.outputOptions('-metadata', `comment=${tags.comment}`);
-      cmd.on('error', (err, so, se) => reject(new Error(((err && err.message) || 'ffmpeg') + (se ? ' | ' + se : ''))))
-         .on('end', () => resolve())
-         .save(tmpPath);
-    });
-    const s = await stat(tmpPath);
-    if (s.size === 0) throw new Error('retag output is empty');
-    await rename(tmpPath, filePath);
-    return { filePath, size: s.size };
-  } catch (err) {
-    try { await unlink(tmpPath); } catch { /* tmp may not exist */ }
-    throw err;
-  }
-}
-
-/**
  * Run a single ffmpeg pass: input -> tmp output.
  * Returns a promise that resolves when ffmpeg exits cleanly, rejects otherwise.
@@ -182,5 +140,4 @@
 function runFfmpeg({ inputPath, tmpPath, tags }) {
   return new Promise((resolve, reject) => {
-    let durationSec = null;
     const cmd = ffmpeg(inputPath)
       .audioCodec('libmp3lame')
@@ -206,14 +163,9 @@
     // breaks any value containing a space (e.g. "Test Artist" gets parsed
     // as a separate output filename).
-    if (tags.title)     cmd.outputOptions('-metadata', `title=${tags.title}`);
-    if (tags.artist)    cmd.outputOptions('-metadata', `artist=${tags.artist}`);
-    if (tags.album)     cmd.outputOptions('-metadata', `album=${tags.album}`);
-    if (tags.copyright) cmd.outputOptions('-metadata', `copyright=${tags.copyright}`); // ID3 TCOP — owner/credit
-    if (tags.comment)   cmd.outputOptions('-metadata', `comment=${tags.comment}`);     // ID3 COMM — license
+    if (tags.title)  cmd.outputOptions('-metadata', `title=${tags.title}`);
+    if (tags.artist) cmd.outputOptions('-metadata', `artist=${tags.artist}`);
+    if (tags.album)  cmd.outputOptions('-metadata', `album=${tags.album}`);
 
     cmd
-      // codecData gives the INPUT duration as "HH:MM:SS.xx" — this lets us
-      // determine the track length automatically without a separate ffprobe binary.
-      .on('codecData', (data) => { durationSec = parseHmsToSeconds(data && data.duration); })
       .on('error', (err, stdout, stderr) => {
         // ffmpeg's stderr is the most useful diagnostic. fluent-ffmpeg's
@@ -224,44 +176,8 @@
         reject(new Error(`Transcode failed: ${reason}${tail ? '\n' + tail : ''}`));
       })
-      .on('end', () => resolve({ durationSec }))
+      .on('end', () => resolve())
       .save(tmpPath);
   });
 }
 
-/**
- * Parse an ffmpeg duration string "HH:MM:SS.xx" to whole seconds. Returns null
- * for "N/A" or an unexpected format.
- */
-function parseHmsToSeconds(hms) {
-  if (!hms || typeof hms !== 'string') return null;
-  const m = hms.match(/^(\d+):(\d{2}):(\d{2})(?:\.(\d+))?$/);
-  if (!m) return null;
-  const sec = (+m[1]) * 3600 + (+m[2]) * 60 + (+m[3]) + (m[4] ? Number('0.' + m[4]) : 0);
-  return Number.isFinite(sec) ? Math.round(sec) : null;
-}
-
-/**
- * Read the duration (whole seconds) of an audio file WITHOUT transcoding.
- * Starts an ffmpeg pass and reads only the codecData event (duration), then
- * kills the process immediately — fast and without a separate ffprobe binary
- * (ffmpeg-static ships only ffmpeg). Intended for the backfill script.
- * @returns {Promise<number|null>}
- */
-export function probeDuration(filePath) {
-  return new Promise((resolve) => {
-    let durationSec = null, done = false;
-    const finish = () => { if (!done) { done = true; resolve(durationSec); } };
-    const cmd = ffmpeg(filePath)
-      .on('codecData', (data) => {
-        durationSec = parseHmsToSeconds(data && data.duration);
-        try { cmd.kill('SIGKILL'); } catch { /* already done */ }
-        finish();
-      })
-      .on('error', finish)
-      .on('end', finish)
-      .format('null')
-      .save(process.platform === 'win32' ? 'NUL' : '/dev/null');
-  });
-}
-
-export default { transcodeToMp3, probeDuration };
+export default { transcodeToMp3 };
