Как загрузить результат FileReader в HTML5 видео для лучшей совместимости между браузерами и устройствами - PullRequest
1 голос
/ 19 апреля 2019

Я пытаюсь загрузить выбранный видеофайл в html5, чтобы пользователь мог просмотреть видео перед отправкой на сервер.

Проблема в том, что при использовании браузеров Chrome и Safari для настольных ПК и мобильных устройств (ios12) он работает только в Chrome для настольных компьютеров.

Обратите внимание, что как только я отправляю этот файл на свой сервер (сохраненный с CarrierWave и загруженный на S3), а затем обновляю видео с новым URL-адресом src, он работает на всех браузерах и устройствах.

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>

Ошибка, которую я вижу в журналах сафари на настольном и мобильном устройствах, - это запись строки base64 («data: video / mp4; base64, ... etc ...») и «Не удалось загрузить ресурс: URL-адрес данных» Ошибка декодирования "

Почему не удается декодирование? Спасибо

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Я просто не использовал 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();
}
1 голос
/ 22 апреля 2019

Вариант 1:

Попробуйте заменить

this.filePreview = e.target.result;

С этим

this.filePreview = (window.URL || window.webkitURL).createObjectURL(file);

Вариант 2:

Вы можете попробовать альтернативный метод загрузки видео в динамический тег видео и посмотреть, работает ли он во всех браузерах HTML5 ...

Тестируемый код (динамически создавайте / уничтожайте <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>
...