1

My users are allowed to upload videos to my site. However an issue came up that some of the video files have a Codec that is not supported by browsers (YUV).

So I want to look into how I can see the codec.

At the moment I'm using multer to process my files:

app.use(multer({
    dest: './uploads/',
    rename: function (fieldname, filename) {
        return filename + Date.now();
    },

    onFileUploadStart: function (file) {
        var i = 0;
    },
    onFileUploadComplete: function (file) {
        //Redirects request to path
        var i = 0;
    }
}));

Setting a breakpoint and inspecting the file the only information I get:

enter image description here

So my question is: Is there any way to see the codec of an uploaded file?

2 Answers 2

3

Firstly, it is worth saying that YUV is a color space rather than a codec - similar to the maybe more easily understood RGB (Red Green Blue) color space. It is a way of representing the brightness and color of the pixels in an image. Many codecs use the YUV color space because it facilitates the type of computations that codecs need to do and it reduces redundancy.

If you do want to find the codec(s) that a particular video file is using, along with quite a bit of other information, then doing a basic analysis to see what type and format of video you have uploaded is quite a hard task as there are so many formats.

I would think the easiest way to do this is to leverage ffprobe functionality if you can:

There are modules that provide a wrapper around ffprobe so you can use it from node - for example:

Using this approach allows you very simply generate video file info which you can then parse for the codec. A usage example from the above link (correct at time of writing):

var probe = require('node-ffprobe');

var track = '/path/to/media/file.mp3';

probe(track, function(err, probeData) {
    console.log(probeData);
});

And and example of the type of output that ffprobe produces for an example of the ubiquitous BigBuckBunny video:

ffprobe version 2.6.1 Copyright (c) 2007-2015 the FFmpeg developers
  built with llvm-gcc 4.2.1 (LLVM build 2336.11.00)
  configuration: --prefix=/Volumes/Ramdisk/sw --enable-gpl --enable-pthreads --enable-version3 --enable-libspeex --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-avfilter --enable-libopencore_amrwb --enable-libopencore_amrnb --enable-filters --enable-libgsm --enable-libvidstab --enable-libx265 --disable-doc --arch=x86_64 --enable-runtime-cpudetect
  libavutil      54. 20.100 / 54. 20.100
  libavcodec     56. 26.100 / 56. 26.100
  libavformat    56. 25.101 / 56. 25.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 11.102 /  5. 11.102
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.../vid_bigbuckbunny.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2010-02-09 01:55:39
  Duration: 00:01:00.10, start: 0.000000, bitrate: 733 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 22050 Hz, stereo, fltp, 65 kb/s (default)
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : Apple Sound Media Handler
    Stream #0:1(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709), 640x360, 612 kb/s, 23.96 fps, 24 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : Apple Video Media Handler
    Stream #0:2(eng): Data: none (rtp  / 0x20707472), 45 kb/s
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : hint media handler
    Stream #0:3(eng): Data: none (rtp  / 0x20707472), 5 kb/s
    Metadata:
      creation_time   : 2010-02-09 01:55:39
      handler_name    : hint media handler

Anything that ffprobe fails to recognise is mostly like not a video or if it is a video it is not going to play in a regular browser anyway.

Its worth checking the ffmpeg/ffprobe licensing to make sure it meets your needs also.

Sign up to request clarification or add additional context in comments.

Comments

0

You can detect codec with the bellow code. I had similar kinds of problem. Some video generated in iphone are in hevc codec. I can get the codec of video with ffprobe. As I had ffmpeg installed before, I just installed ffprobe binary with @ffprobe-installer/ffprobe.

const ffmpeg= require('fluent-ffmpeg');
const ffprobeInstaller = require('@ffprobe-installer/ffprobe');
ffmpeg.setFfprobePath(ffprobeInstaller.path);

/**Get codec of the video file.
 * 
 * @param {*} filePath 
 * @returns codec of the file
 */
const getCodec=(filePath)=>{
    return new Promise((resolve,reject)=>{
        try {
            
            ffmpeg.ffprobe(filePath,function(err, probeData) {
                //console.log("probeData for ",filePath,probeData,err);
                if(err)return reject(err);
                else{
                    return resolve(probeData.streams[0].codec_name);
                }
            });            
        } catch (error) {
            return reject(error);
        }        
    });
    
}
exports.getCodec=getCodec;

Not only that, you can change the codec into playable format with bellow code. This used ffmpeg. Just install npm fluent-ffmpeg:

ffmpeg.setFfmpegPath( require('@ffmpeg-installer/ffmpeg'));
/**Convert video to regular mp4(h.264) codec
 * 
 * @param {*} source 
 * @param {*} destination 
 * @returns 
 */
const convertVideo=(source,destination)=>{
    return new Promise((resolve,reject)=>{
        try {
            ffmpeg(source).videoCodec('libx264').output(destination).on('end', function() {                    
                console.log('conversion ended');
                return resolve(destination);
            }).on('error', function(err){
                console.log('error: ', err.code, err.msg);
                return reject(err);                
            }).run();
            
        } catch (error) {
            return reject(error);
        }        
    });    
}
exports.convertVideo=convertVideo;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.