如何将 FileReader 结果加载到 HTML5 视频中以获得跨浏览器和设备的最佳兼容性
How to load FileReader result into HTML5 video for best compatibility across browsers & devices
我正在尝试将选定的视频文件加载到 html5 中,供用户在将视频发送到服务器之前进行预览。
问题在于,在桌面和移动设备 (ios12) 上使用浏览器 Chrome 和 Safari,它仅适用于桌面 Chrome。
请注意,一旦我将此文件发送到我的服务器(使用 CarrierWave 保存并上传到 S3),然后使用新的 src url 更新视频,它就适用于所有浏览器和设备。
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
this.$scope.$applyAsync(() => {
this.filePreview = e.target.result;
})
}
<video class="video-previewer" ng-if="$ctrl.filePreview" width="{{$ctrl.width}}" height="{{$ctrl.height}}" controls playsinline preload="metadata">
<source ng-src="{{$ctrl.filePreview + '#t=0.5'}}" type="video/mp4">
</video>
我在桌面和移动设备上的 safari 日志中看到的错误是正在记录的 base64 字符串 ("data:video/mp4;base64,...etc...") 和 "Failed to load resource: Data URL decoding failed"
为什么解码失败?谢谢
选项 1:
尝试替换
this.filePreview = e.target.result;
有了这个
this.filePreview = (window.URL || window.webkitURL).createObjectURL(file);
选项 2:
您可以尝试另一种方法将视频加载到动态视频标签中,看看它是否适用于所有 HTML5 浏览器...
可测试代码(根据需要动态 create/destory <video>
标记):
<!DOCTYPE html>
<html>
<body>
<p> Choose a video file...</p>
<input type="file" id="fileChooser" accept="*/*"/>
<div>
<a id="aTag"> </a>
</div>
<script>
document.getElementById('fileChooser').addEventListener('change', onFileSelected, false);
function onFileSelected(evt)
{
var file = evt.target.files[0]; // FileList object
var type = file.type;
//alert("file TYPE is : " + type);
var fileURL = URL.createObjectURL(file);
var reader = new FileReader();
reader.readAsDataURL(file);
var tmpElement; //will container the video content....
var path; //will hold URL of file BLOB (is not file path)....
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
//# update file path...
path = (window.URL || window.webkitURL).createObjectURL(file);
//# remove any other existing media element...
var container = document.getElementById("aTag");
if (container.hasChildNodes())
{ container.removeChild(container.childNodes[0]); }
if ( type == "video/mp4" )
{
tmpElement = document.createElement( "video");
tmpElement.setAttribute("controls", "true" );
tmpElement.setAttribute("width", "800");
}
else
{ return 0; } //break out / cancel
//# add newly created HTML5 element with file path
tmpElement.setAttribute("src", path);
container.appendChild(tmpElement);
}
};
}
</script>
</body>
</html>
我最终没有对视频使用 FileReader
,而是直接在文件上使用 URL.createObjectURL(file)
,它正在运行。
onFileUpload({ file }) {
const URL = window.URL || window.webkitURL;
const vid = document.getElementById('#id-for-video-preview-element');
vid.src = URL.createObjectURL(file);
vid.load();
}
我正在尝试将选定的视频文件加载到 html5 中,供用户在将视频发送到服务器之前进行预览。
问题在于,在桌面和移动设备 (ios12) 上使用浏览器 Chrome 和 Safari,它仅适用于桌面 Chrome。
请注意,一旦我将此文件发送到我的服务器(使用 CarrierWave 保存并上传到 S3),然后使用新的 src url 更新视频,它就适用于所有浏览器和设备。
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
this.$scope.$applyAsync(() => {
this.filePreview = e.target.result;
})
}
<video class="video-previewer" ng-if="$ctrl.filePreview" width="{{$ctrl.width}}" height="{{$ctrl.height}}" controls playsinline preload="metadata">
<source ng-src="{{$ctrl.filePreview + '#t=0.5'}}" type="video/mp4">
</video>
我在桌面和移动设备上的 safari 日志中看到的错误是正在记录的 base64 字符串 ("data:video/mp4;base64,...etc...") 和 "Failed to load resource: Data URL decoding failed"
为什么解码失败?谢谢
选项 1:
尝试替换
this.filePreview = e.target.result;
有了这个
this.filePreview = (window.URL || window.webkitURL).createObjectURL(file);
选项 2:
您可以尝试另一种方法将视频加载到动态视频标签中,看看它是否适用于所有 HTML5 浏览器...
可测试代码(根据需要动态 create/destory <video>
标记):
<!DOCTYPE html>
<html>
<body>
<p> Choose a video file...</p>
<input type="file" id="fileChooser" accept="*/*"/>
<div>
<a id="aTag"> </a>
</div>
<script>
document.getElementById('fileChooser').addEventListener('change', onFileSelected, false);
function onFileSelected(evt)
{
var file = evt.target.files[0]; // FileList object
var type = file.type;
//alert("file TYPE is : " + type);
var fileURL = URL.createObjectURL(file);
var reader = new FileReader();
reader.readAsDataURL(file);
var tmpElement; //will container the video content....
var path; //will hold URL of file BLOB (is not file path)....
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
//# update file path...
path = (window.URL || window.webkitURL).createObjectURL(file);
//# remove any other existing media element...
var container = document.getElementById("aTag");
if (container.hasChildNodes())
{ container.removeChild(container.childNodes[0]); }
if ( type == "video/mp4" )
{
tmpElement = document.createElement( "video");
tmpElement.setAttribute("controls", "true" );
tmpElement.setAttribute("width", "800");
}
else
{ return 0; } //break out / cancel
//# add newly created HTML5 element with file path
tmpElement.setAttribute("src", path);
container.appendChild(tmpElement);
}
};
}
</script>
</body>
</html>
我最终没有对视频使用 FileReader
,而是直接在文件上使用 URL.createObjectURL(file)
,它正在运行。
onFileUpload({ file }) {
const URL = window.URL || window.webkitURL;
const vid = document.getElementById('#id-for-video-preview-element');
vid.src = URL.createObjectURL(file);
vid.load();
}