简体   繁体   English

Node.js 视频上传获取 Codec

[英]Node.js video upload get Codec

My users are allowed to upload videoes to my site.我的用户可以将视频上传到我的网站。 However an issue came up that some of the video files have a Codec that is not supported by browsers (YUV) .然而,出现了一个问题,即某些视频文件的编解码器不受浏览器(YUV)支持。

So i want to look into how i can see the codec.所以我想研究一下如何查看编解码器。

At the moment im using multer to process my files:目前我使用multer来处理我的文件:

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:设置断点并检查文件我得到的唯一信息:

在此处输入图片说明

So my question is: Is there anyway to see the codec of an uploaded file?所以我的问题是:反正有没有看到上传文件的编解码器?

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. 首先,值得一提的是YUV是一个色彩空间,而不是编解码器-类似于也许更容易理解的RGB(红色绿色蓝色)色彩空间。 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. 许多编解码器使用YUV颜色空间,因为它可以简化编解码器需要执行的计算类型,并减少冗余。

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: 我认为最简单的方法是利用ffprobe功能,如果可以的话:

There are modules that provide a wrapper around ffprobe so you can use it from node - for example: 有一些模块提供了ffprobe的包装器,因此您可以从节点使用它-例如:

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为无处不在的BigBuckBunny视频示例生成的输出类型示例:

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. ffprobe无法识别的任何内容都大都像不是视频,或者如果是视频,则无论如何都无法在常规浏览器中播放。

Its worth checking the ffmpeg/ffprobe licensing to make sure it meets your needs also. 值得检查ffmpeg / ffprobe许可以确保它也满足您的需求。

You can detect codec with the bellow code.您可以使用以下代码检测编解码器。 I had similar kinds of problem.我有类似的问题。 Some video generated in iphone are in hevc codec.在 iphone 中生成的一些视频是 hevc 编解码器。 I can get the codec of video with ffprobe.我可以使用 ffprobe 获取视频的编解码器。 As I had ffmpeg installed before, I just installed ffprobe binary with @ffprobe-installer/ffprobe.因为我之前安装了 ffmpeg,所以我只是用 @ffprobe-installer/ffprobe 安装了 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.这使用了ffmpeg。 Just install npm fluent-ffmpeg:只需安装 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM