最近在弄视频文件播放,出现了给video标签src赋视频文件路径,但是用来测试的mp4文件可以正常显示,而tup运行时生成的mp4文件却不能显示,video标签已经读取了mp4文件的资源,但是显示为空白。

经过百度,h5的video标签对于mp4格式视频文件只支持h264编码,与tup沟通后将生成编码转为h264可以正常读取显示,

今天一位朋友Q我说:为什么我录制的MP4视频在本地可以播放但是使用html5的video多媒体播放标签不能正常播放只有一个进度条而不显示图像?当时我也很好奇MP4视频可以用video标签播放呀,我就经常用,毕竟是好朋友我还是亲自去筛查了一下问题,这不结论处来了,其实就是一个视频编码的问题,格式虽然都是MP4但是html中只支持H.264的编码格式,无奈只能重新转换一下编码了。

为了避免大家遇到同样的问题我在这里就给大家普及一下html5关于<video>标签的知识吧:

在使用html4协议做网站时我们想要在网页上播放一个视频要不使用flash去播放,要么就是嵌入式页面来实现,对于html5来说这两种方法非常的不方便因为一个牛逼哄哄的<video>出现了,这个标签的功能就是让多媒体文件可以很方便的在网页中播放。

html中播放一个视频只需要一个标签:

    1. <video src="http://sp.ntaotu.com/localhost-wordpress-phpstudy.mp4" controls="controls" width="500" height="300"></video>
    代码虽然少了很多,但是功能却很健全,这就是html5的亮点之一吧!

    关于<video>标签所支持的视频格式和编码:

    • MP4 = MPEG 4文件使用 H264 视频编解码器和AAC音频编解码器
    • WebM = WebM 文件使用 VP8 视频编解码器和 Vorbis 音频编解码器
    • Ogg = Ogg 文件使用 Theora 视频编解码器和 Vorbis音频编解码器

    通过上面的信息我们会发现只有h264编码的MP4视频(MPEG-LA公司)、VP8编码的webm格式的视频(Google公司)和Theora编码的ogg格式的视频(iTouch开发)可以支持html5的<video>标签。

    如果浏览器不支持video标签怎么办?

    比如IE浏览器还有老版本的浏览器对html5的支持不太好,当用户用这些浏览器打开我们带有视频的网页怎么办呢?

    我们可以把代码这样写:

    1. <video src="http://sp.ntaotu.com/localhost-wordpress-phpstudy.mp4" controls="controls" width="500" height="300">您的浏览器不支持播放该视频!</video>

    这样在不支持html5的浏览器中就会提示“您的浏览器不支持播放该视频!”啦!

    关于video标签的扩展参数说明:

    video 元素允许多个 source 元素。source 元素可以链接不同的视频文件。浏览器将使用第一个可识别的格式,这样我们只要多准备几个不同格式的视频就可以了。

    用法:

    1. <video width="500" height="250" controls="controls">
    2. <source src="movie.ogg" type="video/ogg">
    3. <source src="movie.mp4" type="video/mp4">
    4. 您的浏览器不支持此种视频格式。
    5. </video>
    6. autoplay :出现该属性意味着视频在就绪后将自动播放,用法:autoplay="autoplay"
    7. controls :出现该属性意味着向用户显示控件,如播放按钮等,用法:controls="controls"
    8. height:设置高度 width:设置宽度
    9. loop:自动重播,用法:loop="loop"
    10. preload:视频在页面加载时进行加载并预备播放,用法:preload="auto" - 当页面加载后载入整个视频;preload="meta" - 当页面加载后只载入元数据;preload="none" - 当页面加载后不载入视频。注意:若使用了autoplay,则忽略preload
    11. src:要播放视频的url

     

    黄总在做进度条控制双视频同步拖进度的过程中,一开始在单页面做的时候拖动进度播放正常,但是在将代码加入到react之后出现了拖动进度条视频播放总是从头开始的情况,他后面尝试了将视频播放的代码当做一个页面用<iframe>标签嵌入到react中还是没能解决。

    后来经过讨论,发现是我们项目自己写的http服务器功能简陋的问题,每次浏览器读取mp4文件都会从头开始重新读取,而他做单页面的时候用的是apache服务器,所以能记录视频文件播放进度。

    所以黄总在读取mp4文件的时候用了新的npm模块

    const mfs = require("mz/fs");

    mz这个模块是原来用的fs模块的扩展版

    const fs = require('fs');

    原来读取mp4文件

    console.log("Client require :"+pathname);
    //Data = fs.readFileSync(".."+pathname,'binary');
    response.writeHead(200, {
        "Content-Type": "video/mpeg4"
    });
    //response.write(Data);
    //response.end();
    file = APP_PATH + "/../zhmed" + pathname;
    fs.stat(file, function (err, stat) {
        var img = fs.readFileSync(file);
        response.contentType = 'application/x-font-ttf';
        response.contentLength = stat.size;
        response.end(img, 'binary');
    });
    break;

    更换模块后

    let range = request.headers["range"];
    // let p = "."+pathname;//path.resovle(__dirname, url.parse(request.url, true).pathname);
    // let p = APP_PATH + '/../zhmed' + pathname
    let p = '../zhmed' + pathname
    if (range) {
        let [, start, end] = range.match(/(\d*)-(\d*)/);
        let statObj;
        try {
            statObj = await mfs.stat(p);
        } catch (e) {
            console.log(e.message);
            response.end("Not Found");
            break;
        }
        let total = statObj.size;
        start = start ? parseInt(start) : 0;
        end = end ? parseInt(end) : total - 1;
        response.statusCode = 206;
        response.setHeader("Accept-Ranges", "bytes");
        response.setHeader("Content-Range", `bytes ${start}-${end}/${total}`);
        mfs.createReadStream(p, { start, end }).pipe(response);
    } else {
        mfs.createReadStream(p).pipe(response);
    }
    break;