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

Performance Improvement #72

Open
Astropilot opened this issue Sep 15, 2020 · 2 comments
Open

Performance Improvement #72

Astropilot opened this issue Sep 15, 2020 · 2 comments

Comments

@Astropilot
Copy link

Having tried to generate a thumbnail of an MP4 video, I noticed that running ffmpeg took a lot of time to retrieve a thumbnail from a given time in the video. Upon inquiring, I found this comment interesting (https://superuser.com/a/821680)

Each invocation of above ffmpeg command takes a fraction of second (!) for ~1GB H.264. That is because it instantly jumps to position (mind -ss before -i) and takes first key frame which is practically complete JPEG. There is no time wasted for rendering the movie to match exact time position.

Currently in the creation of arguments for ffmpeg the argument -ss is placed after the definition of the source file.
https://github.com/ScottyFillups/simple-thumbnail/blob/44379e88307c1aa2c8efee518dd2c1d4861eb566/index.js#L60-L68

I have therefore rearranged the order of the arguments to put the -ss before the -i as suggested in the comment above.

return [
  '-y',
  `-ss ${seek}`,
  `-i ${input}`,
  scaleArg,
  '-vframes 1',
  output
]

For the following test script with an MP4 file of 23m40s and 188Mb I give you the total execution time of this same script with the original order and the one I propose.

The script:

const ffmpeg = require('ffmpeg-static')
const genThumbnail = require('simple-thumbnail')

async function download () {
  await genThumbnail('test.mp4', 'test_s.jpg', '150x?', {
    path: ffmpeg,
	seek: '00:12:00'
  })
  console.log('Done!')
}

download()

The characteristics of the MP4 file (the return of ffprobe):

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.33.100
  Duration: 00:23:40.16, start: 0.000000, bitrate: 1113 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 915 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 192 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

The execution time of the script with the original order:

PS C:\Users\marti\Documents\test> Measure-Command {node .\index.js}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 18
Milliseconds      : 188
Ticks             : 181882832
TotalDays         : 0,000210512537037037
TotalHours        : 0,00505230088888889
TotalMinutes      : 0,303138053333333
TotalSeconds      : 18,1882832
TotalMilliseconds : 18188,2832

The execution time of the script with the proposed order:

PS C:\Users\marti\Documents\test> Measure-Command {node .\index.js}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 480
Ticks             : 14806789
TotalDays         : 1,71374872685185E-05
TotalHours        : 0,000411299694444444
TotalMinutes      : 0,0246779816666667
TotalSeconds      : 1,4806789
TotalMilliseconds : 1480,6789

The time saving is huge for me, and I see the same time saving if I provide the MP4 file via a URL and not as a local file.

The execution time of the script with the file over the internet with the original order:

PS C:\Users\marti\Documents\test> Measure-Command {node .\index.js}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 26
Milliseconds      : 18
Ticks             : 260180286
TotalDays         : 0,000301134590277778
TotalHours        : 0,00722723016666667
TotalMinutes      : 0,43363381
TotalSeconds      : 26,0180286
TotalMilliseconds : 26018,0286

The execution time of the script with the file over the internet with the proposed order:

PS C:\Users\marti\Documents\test> Measure-Command {node .\index.js}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 2
Milliseconds      : 265
Ticks             : 22658406
TotalDays         : 2,62250069444444E-05
TotalHours        : 0,000629400166666667
TotalMinutes      : 0,03776401
TotalSeconds      : 2,2658406
TotalMilliseconds : 2265,8406

My tests were performed on a Windows 10 Pro 64bits with an Intel Core i7-10510U.

The order of the parameters definitely seems to have an importance on the performance of ffmpeg, unfortunately I don't have time to do more tests but I'll let you try on your side too.

This is my first issue and I hope I have respected the rules as much as possible 😢

Have a nice day !

@philipjscott
Copy link
Owner

This is honestly the most well-structured issue I have ever seen.

@alexreal1314
Copy link

is this going to get fixed in the next release?

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

No branches or pull requests

3 participants