Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tdarr_Plugin_076a_re_order_audio_streams will delete container attachments #792

Open
gabehf opened this issue Mar 3, 2025 · 0 comments · May be fixed by #794
Open

Tdarr_Plugin_076a_re_order_audio_streams will delete container attachments #792

gabehf opened this issue Mar 3, 2025 · 0 comments · May be fixed by #794

Comments

@gabehf
Copy link

gabehf commented Mar 3, 2025

I noticed that every time this plugin ran, all of the attached fonts on the file were deleted. Upon inspection, it seems as though the streams are mapped, but there is no mapping for attachments -map 0:t?. This is of course very bad for a plugin marked as "audio only". I only wish I had caught this bug before it processed thousands of my anime episodes.

For anyone looking to do what I was doing (set an audio track as default based on language, not quite the same as this plugin) and you want a copy-paste solution, this plugin I wrote will set the first audio track it finds in a specified language as default (but it won't change the position of the stream).

/* eslint max-len: 0, no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
const details = () => ({
    id: 'Tdarr_Plugin_gabehf_Make_First_Audio_In_Lang_Default',
    Stage: 'Pre-processing',
    Name: 'Make First Audio In The Preferred Language Default',
    Type: 'Audio',
    Operation: 'Transcode',
    Description:
      'If no audio in the preferred language are made default already, this plugin sets the first audio stream in that language as default. \\n',
    Version: '1.0',
    Tags: 'pre-processing,ffmpeg,audio only,configurable',
    Inputs: [{
      name: 'preferred_language',
      type: 'string',
      defaultValue: 'jpn',
      inputUI: {
        type: 'text',
      },
      tooltip:
        'Your preferred language code(s) in ISO 639-2 language scheme, separated by a comma. Only the first track that matches any of these language codes will be made default. \\n Default: eng,en',
    }],
  });
  
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const plugin = (file, librarySettings, inputs, otherArguments) => {
    const lib = require('../methods/lib')();
    // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-param-reassign
    inputs = lib.loadDefaultValues(inputs, details);
    var languages = []
    if (inputs.preferred_language == "") {
        languages = ["jpn"]; //these languages should be kept, named according to ISO 639-2 language scheme
    } else {
        languages = inputs.preferred_language.toLowerCase().split(","); //these languages should be kept, named according to ISO 639-2 language scheme
    }

    const response = {
      processFile: false,
      preset: '',
      container: `.${file.container}`,
      handBrakeMode: false,
      FFmpegMode: true,
      reQueueAfter: false,
      infoLog: '',
    };
  
    // Check if file is a video. If it isn't then exit plugin.
    if (file.fileMedium !== 'video') {
      // eslint-disable-next-line no-console
      console.log('File is not video');
      response.infoLog += '☒File is not video \n';
      response.processFile = false;
      return response;
    }
  
    // Set up required variables.
    let ffmpegCommandInsert = '';
    let audioIdx = 0;
    let convert = false;
    let defaults = [] // list of tracks currently set as default
    
    for (let i = 0; i < file.ffProbeData.streams.length; i++) {
      try {
        if (file.ffProbeData.streams[i].codec_type.toLowerCase() === 'audio') {
            defaults[audioIdx] = file.ffProbeData.streams[i].disposition.default === 1
            if (!convert && file.ffProbeData.streams[i].disposition.default === 0 && languages.includes(file.ffProbeData.streams[i].tags.language)) {
                convert = true;
                ffmpegCommandInsert += `-disposition:a:${audioIdx} default `;
                response.infoLog += `☒Audio stream 0:a:${audioIdx} is the first track in preferred language and not currently default; setting as default. \n`;
            } else if (file.ffProbeData.streams[i].disposition.default === 1 && languages.includes(file.ffProbeData.streams[i].tags.language)) {
                // if any audio with the preferred language is marked default, no action is needed.
                convert = false;
                response.infoLog = '';
                break;
            }
          audioIdx += 1;
        }
        } catch (err) {
            // Error
        }
    }

    if (convert) {
        // remove previous default(s)
        for (let i = 0; i < defaults.length; i++) {
            if (defaults[i]) {
                ffmpegCommandInsert += `-disposition:a:${i} 0 `;
                response.infoLog += `☒Audio stream 0:a:${i} was default but not in preferred language; removing disposition. \n`;
            }
        }
    } 
  
    // Convert file if convert variable is set to true.
    if (convert === true) {
      response.processFile = true;
      response.preset = `, -map 0 ${ffmpegCommandInsert}-c copy -max_muxing_queue_size 9999`;
      response.container = `.${file.container}`;
      response.reQueueAfter = true;
    } else {
      response.processFile = false;
      response.infoLog += "☑File doesn't contain audio tracks that require modification.\n";
    }
    return response;
  };
  module.exports.details = details;
  module.exports.plugin = plugin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant