Closed yyqangular1 closed 4 years ago
可以传一下不能播的文件吗?
@sonysuqin 我上传到百度网盘了。 链接: https://pan.baidu.com/s/1uYOVkEWJ8_GgfixsoSMU-w 提取码: bykj
另外,我还发现,貌似是文件很大后,就无法播放了,几分钟,有很多都可以播。十几分钟的可能就无法播放了。比如您demo中带的那个屌丝男士的7分多的视频,如果把两个拼接成一个15分钟的视频,就无法播放了。。我上传的那个视频就是您的原视频拼接的。 我本地实验了很多个视频,暂时发现临界点好像是12分钟,超过12分钟就播不了了,12分钟以内的目前不管是hev1还是hvc1都可以播放。
另外,我还发现,貌似是文件很大后,就无法播放了,几分钟,有很多都可以播。十几分钟的可能就无法播放了。比如您demo中带的那个屌丝男士的7分多的视频,如果把两个拼接成一个15分钟的视频,就无法播放了。。我上传的那个视频就是您的原视频拼接的。 我本地实验了很多个视频,暂时发现临界点好像是12分钟,超过12分钟就播不了了,12分钟以内的目前不管是hev1还是hvc1都可以播放。
是不是mp4文件,waitHeaderLength设置大一点,文件越大头越大
另外,我还发现,貌似是文件很大后,就无法播放了,几分钟,有很多都可以播。十几分钟的可能就无法播放了。比如您demo中带的那个屌丝男士的7分多的视频,如果把两个拼接成一个15分钟的视频,就无法播放了。。我上传的那个视频就是您的原视频拼接的。 我本地实验了很多个视频,暂时发现临界点好像是12分钟,超过12分钟就播不了了,12分钟以内的目前不管是hev1还是hvc1都可以播放。
是不是mp4文件,waitHeaderLength设置大一点,文件越大头越大
@pzx601917159 我也尝试过把waitHeaderLength放大2~10倍,但是还是一样的错误,看错误信息确实也是获取不到头信息。
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x644ba0] reached eof, corrupted STCO atom
libffmpeg.js:2012 [mov,mp4,m4a,3gp,3g2,mj2 @ 0x644ba0] error reading header
@pzx601917159 试了一下你传的文件,可以播,跟 @yyqangular1 说的一样,就是文件大了之后头也变大,改的地方是index.html里的: self.player.play(videoFileUrl, canvas, function (e) { console.log("play error " + e.error + " status " + e.status + "."); if (e.error == 1) { logger.logInfo("Finished."); } }, 1024000);
@pzx601917159 试了一下你传的文件,可以播,跟 @yyqangular1 说的一样,就是文件大了之后头也变大,改的地方是index.html里的: self.player.play(videoFileUrl, canvas, function (e) { console.log("play error " + e.error + " status " + e.status + "."); if (e.error == 1) { logger.logInfo("Finished."); } }, 1024000);
@sonysuqin 改大之后确实可以了,我这里的视频文件基本都是2个小时时长的,这个头的大小不好把控,1024000这个值在2个小时时长的视频也是无法播放的。只能放的更大。这个文件头最大能到多少我也没查到相关资料。
另外还有一个问题,比较大的视频,播放的时候,点击两次seek,浏览器直接出现崩溃了。
文件越大头越大,加载时间越长,一般都是切成分段的,这样可以控制加载时间。
@yyqangular1 @sonysuqin
我之前也提了这个问题
https://github.com/sonysuqin/WasmVideoPlayer/issues/25
针对mp4文件我自己实现了一个方法解析mp4 header的长度,不知道有没有更好的方法,可以参考一下
主要做两点:
1.判断mp4 moov是不是在mdat之前,如果不是这个要加载的文件尾播放(这里要参考ffmpeg想方法兼容)
2.如果moov在mdat之前,mp4的header长度 ftyp+moov的长度
代码如下:
unsigned int getU32(char* buf)
{
unsigned int ret;
memcpy(&ret, buf, 4);
return htonl(ret);
}
int getMp4HeaderSize()
{
int ret = 0;
do
{
if (decoder == NULL || decoder->fp == NULL) {
ret = -1;
break;
}
fseek(decoder->fp, 0, SEEK_SET);
int availableBytes = decoder->fileWritePos;
if(availableBytes < 8)
{
break;
}
char buf[8];
int size = 0;
int tag_type = 0;
while(tag_type != MKTAG('m','o','o','v') && ret < availableBytes)
{
fseek(decoder->fp, ret, SEEK_SET);
memset(buf, 0, sizeof(buf));
fread(buf, 8, 1, decoder->fp);
size = getU32(buf);
tag_type = MKTAG(buf[4],buf[5],buf[6],buf[7]);
if(tag_type == MKTAG('m','d','a','t'))
{
ret = -1;
break;
}
ret += size;
}
}while(0);
return ret;
}
@yyqangular1 @sonysuqin 我之前也提了这个问题
25
针对mp4文件我自己实现了一个方法解析mp4 header的长度,不知道有没有更好的方法,可以参考一下 主要做两点: 1.判断mp4 moov是不是在mdat之前,如果不是这个要加载的文件尾播放(这里要参考ffmpeg想方法兼容) 2.如果moov在mdat之前,mp4的header长度 ftyp+moov的长度 代码如下: unsigned int getU32(char* buf) { unsigned int ret; memcpy(&ret, buf, 4); return htonl(ret); } int getMp4HeaderSize() { int ret = 0; do { if (decoder == NULL || decoder->fp == NULL) { ret = -1; break; } fseek(decoder->fp, 0, SEEK_SET); int availableBytes = decoder->fileWritePos; if(availableBytes < 8) { break; } char buf[8]; int size = 0; int tag_type = 0; while(tag_type != MKTAG('m','o','o','v') && ret < availableBytes) { fseek(decoder->fp, ret, SEEK_SET); memset(buf, 0, sizeof(buf)); fread(buf, 8, 1, decoder->fp); size = getU32(buf); tag_type = MKTAG(buf[4],buf[5],buf[6],buf[7]); if(tag_type == MKTAG('m','d','a','t')) { ret = -1; break; } ret += size; } }while(0); return ret; }
我看了您写的这个判断方法,这个方法什么时候用呢?如果播放的时候先跑这个,那延迟的时间应该会更加长吧。
@yyqangular1 @sonysuqin 我之前也提了这个问题
25
针对mp4文件我自己实现了一个方法解析mp4 header的长度,不知道有没有更好的方法,可以参考一下 主要做两点: 1.判断mp4 moov是不是在mdat之前,如果不是这个要加载的文件尾播放(这里要参考ffmpeg想方法兼容) 2.如果moov在mdat之前,mp4的header长度 ftyp+moov的长度 代码如下: unsigned int getU32(char* buf) { unsigned int ret; memcpy(&ret, buf, 4); return htonl(ret); } int getMp4HeaderSize() { int ret = 0; do { if (decoder == NULL || decoder->fp == NULL) { ret = -1; break; } fseek(decoder->fp, 0, SEEK_SET); int availableBytes = decoder->fileWritePos; if(availableBytes < 8) { break; } char buf[8]; int size = 0; int tag_type = 0; while(tag_type != MKTAG('m','o','o','v') && ret < availableBytes) { fseek(decoder->fp, ret, SEEK_SET); memset(buf, 0, sizeof(buf)); fread(buf, 8, 1, decoder->fp); size = getU32(buf); tag_type = MKTAG(buf[4],buf[5],buf[6],buf[7]); if(tag_type == MKTAG('m','d','a','t')) { ret = -1; break; } ret += size; } }while(0); return ret; }
我看了您写的这个判断方法,这个方法什么时候用呢?如果播放的时候先跑这个,那延迟的时间应该会更加长吧。
我是想得到mp4的header大小,然后在js里面动态设置大小,因为设置太大了,首屏会很慢,设置太小了视频会无法播放。
@yyqangular1 @sonysuqin 我之前也提了这个问题
25
针对mp4文件我自己实现了一个方法解析mp4 header的长度,不知道有没有更好的方法,可以参考一下 主要做两点: 1.判断mp4 moov是不是在mdat之前,如果不是这个要加载的文件尾播放(这里要参考ffmpeg想方法兼容) 2.如果moov在mdat之前,mp4的header长度 ftyp+moov的长度 代码如下: unsigned int getU32(char* buf) { unsigned int ret; memcpy(&ret, buf, 4); return htonl(ret); } int getMp4HeaderSize() { int ret = 0; do { if (decoder == NULL || decoder->fp == NULL) { ret = -1; break; } fseek(decoder->fp, 0, SEEK_SET); int availableBytes = decoder->fileWritePos; if(availableBytes < 8) { break; } char buf[8]; int size = 0; int tag_type = 0; while(tag_type != MKTAG('m','o','o','v') && ret < availableBytes) { fseek(decoder->fp, ret, SEEK_SET); memset(buf, 0, sizeof(buf)); fread(buf, 8, 1, decoder->fp); size = getU32(buf); tag_type = MKTAG(buf[4],buf[5],buf[6],buf[7]); if(tag_type == MKTAG('m','d','a','t')) { ret = -1; break; } ret += size; } }while(0); return ret; }
我看了您写的这个判断方法,这个方法什么时候用呢?如果播放的时候先跑这个,那延迟的时间应该会更加长吧。
我是想得到mp4的header大小,然后在js里面动态设置大小,因为设置太大了,首屏会很慢,设置太小了视频会无法播放。
嗯,目前确实没有其他较好的解决办法。越大的视频目前遇到的问题也较多。 本问题票就先关闭了,感谢各位大佬。
之前发现hev1的h265视频无法播放,现在发现hvc1的h265视频也有无法播放的,这是什么情况?应该如何debug调查? 报错如下:
视频媒体信息如下: