h2non / videoshow

Simple node.js utility to create video slideshows from images with optional audio and visual effects using ffmpeg
MIT License
877 stars 161 forks source link

There is no possibility to provide additional settings for ffmpeg subtitles #86

Open MikeKoval opened 4 years ago

MikeKoval commented 4 years ago

I spent much time trying to understand why MarginR and custom font are not working for my fullhd video, then I bumped into documentation of ffmpeg http://ffmpeg.org/ffmpeg-all.html#subtitles-1 and found that there are additional properties original_size and fontsdir but videshow has only basic option of providing subtitles to ffmpeg so it's impossible to reach what I need(

    if (subtitles) {
      options.push('-vf subtitles=\'' + subtitles + '\'')
    }
MikeKoval commented 4 years ago

Figured out that original_size does not have any impact on .ass margins while PlayResX and PlayResY in Script Info of .ass do, PlayResY=800 is hardcoded so it's impossible to change it. My PR changes signature, so probably lib requires major version update or maybe you suggest other way of setting these options without signature changing and major update?

Here is how it works for me:

const subtitleStyle = {
  Fontname: 'Domus-Light',
  Fontsize: '42',
  PrimaryColour: '&H000000&',
  Bold: '0',
  Italic: '0',
  BorderStyle: '0',
  Outline: '0',
  Shadow: '0',
  Alignment: '5',
  MarginL: '40',
  MarginR: '40',
  MarginV: '100',
};

const subtitleOptions = {
  fontsdir: path.join(__dirname, '../src/api/static'),
};

const MarginR = `${+subtitleStyle.MarginR + width / 2}`;

        const srt = substation.stringify(subtitles, {
          'V4 Styles': {
            Style: {
              ...subtitleStyle,
              MarginR,
            },
          },
          'Script Info': {
            PlayResX: width,
            PlayResY: height,
          },
        });

 return fs.writeFile(filename, srt, err => {
          if (err) {
            return cb(err);
          }

          return cb(null, filename);
        });

----

 const video = videoshow(
            [
              {
                path: slideImageWithTitle,
                loop: duration,
                transition: false,
              },
            ],
            {
              size: `${width}x${height}`,
              format: 'mp4',
              audioCodec: 'aac',
              mime: 'video/mp4',
              videoCodec: 'libx264',
              outputOptions,
              subtitleOptions,
            },
          )
.subtitles(subtitles)
.audio(slideAudio);