2013-11-14 2 views
4

У меня есть элемент видео с наложением холста. Затем у меня есть настройка инструмента рисования, чтобы нарисовать видео и кнопку сохранения, которая делает drawImage как из видео, так и из холста, чтобы сохранить скомпилированный кадр. Однако, в первый раз, когда я нажимаю «Сохранить», я получаю результат только от холста drawImage, видео не отображается. При последующих Сэйвах я получаю оба изображения, правильно слоистые. Я подумал, что это может быть проблемой при загрузке видеоизображения, но видео полностью загружено, прежде чем я удалю по нему, и может даже продвигать кадры и работать с ним на втором сохранении.HTML5 Холст drawImage из видео, не показывающегося при первом розыгрыше

Вот код ...

<div style="width:960px; height:540px; display:inline-block;"> 
    <video id="video" src="media/_tmp/AA_017_COMP_v37.mov" width="960" height="540" ></video> 
</div> 
<canvas id="canvas" width="960" height="540" style="position:absolute; top:40px; left:9px; z-index:100;"></canvas> 
<input type="button" value="save" id="btn" size="30" onclick="save()" style="float:left; padding:4px; margin-right:4px;" > 
<div id="saved" style="border:1px solid #000; position:absolute; top:626px; left:10px; bottom:40px; width:958px; overflow:auto;">SAVED:</div> 


function save() { 

    //COMP CANVAS OVER VIDEOFRAME 
    var video = document.getElementById("video"); 
    var currentFrame = Math.floor((<?php echo $mov_frames ?>/video.duration) * video.currentTime); 

    var compCanvas = document.createElement('canvas'); 
    compCanvas.width = video.width; 
    compCanvas.height = video.height; 
    compContext = compCanvas.getContext('2d'); 
    compContext.drawImage(video, 0, 0); 
    compContext.drawImage(canvas, 0, 0); 
    var dataURL = compCanvas.toDataURL(); 

    $("#saved").append('<div style="width:954px; border-bottom:1px solid #000; padding:2px 2px 0 2px;"><img id="compFrame_'+currentFrame+'" width="180" height="90" src="'+dataURL+'" />Frame: '+currentFrame+'</div>'); 
} 
+0

Можете ли вы предоставить jsfiddle показывая проблему? – Oriol

+0

Вот ссылка [jsFiddle] (http://jsfiddle.net/zL8KC/) Единственная проблема, которую я не знаю для jsFiddle, - это кросс-видеоролик, который не будет рисовать на холсте ... но никогда код отсутствует. –

+0

Ваш код запускается только после загрузки DOM? – GameAlchemist

ответ

2

Как это на OSX с Safari есть некоторые плохие новости:

Примечание: Видео в качестве источника для холста DrawImage() метод не в настоящее время поддерживается на iOS.

Source

Если это устаревшая информация, которую я не знаю, но в любом случае, текущая реализация имеет проблемы. Как установлено (в комментариях), проблема вряд ли связана с кодеками, так как это происходит и с другими форматами. fiddle исключает метод toDataURL() в качестве источника, поэтому остальным является метод drawImage().

Как это работает на другой платформе с предоставленным кодом и из-за ее внешнего вида, это не является источником проблемы, поэтому вы здесь смотрите на очень возможную проблему (ошибка) с браузером Safari на OSX Платформа.

В приведенной выше официальной документации указано, что это не поддерживается, поэтому это, вероятно, очень ранняя реализация, которая по-прежнему имеет некоторые проблемы.

В этом отношении вы не можете многого сделать, но подождать и сообщить об этом как о проблеме (я искал сообщение об ошибке, но не смог найти его, поэтому я рекомендую вам это сделать).

+0

Я считаю, что ты прав. Попытка этого на firefox на OSX, а также на Chrome и FireFox на Win7 все, похоже, создает правильное поведение. –

+0

На самом деле, вернувшись и прочитав исходную ссылку, я понял, что iOS специально не поддерживается. Mavericks на настольной системе не iOS. Однако, похоже, он напрямую связан с Safari, поэтому он все равно может быть ошибкой. –

1

Я недавно столкнулся с тем же вопросом и работал вокруг него, рисуя видео на «манекен», прежде чем делать «настоящую» работу с ним. Это хорошо работает, так как все методы моего кода, которые пытаются разобрать видео, ожидают, пока на видео не будет запущено событие «canplaythrough». Я переношу обработчик событий «canplaythrough» в Promise и разрешаю только обещание, когда получено событие «canplaythrough», и была сделана попытка нарисовать видео на фиктивный холст. This appears to be an effective workaround для ошибки Safari.

Например:

var readyPromise = new Promise(function(resolve) { 
    video.addEventListener("canplaythrough", function() { 
     var canvas = document.createElement("canvas"), 
      context = canvas.getContext("2d"); 

     context.drawImage(video, 0, 0); 

     resolve(video); 
    }); 
}); 

readyPromise.then(function() { 
    // NOW manipulate the video, draw it onto a canvas, etc 
}); 
1

я встретил тот же вопрос и опробовали решение в последний комментарий. Это еще не сработало для меня.

я понял позже, и нашел обходной путь:

в моем коде у меня есть какой-то другой рисунок вместе с DrawImage из видео, как

context.rect(0, 0, 50, 50); 
context.fillStyle = 'black'; 
context.fill(); 

и с них, второй розыгрыш еще не будет работать, даже когда перерисовываете его после события «canplaythrough».

Итак, я удалил вышеуказанные три строки и просто сделал вторую ничью после события «canplaythrough». Тогда это сработало.

Просто код, который работал для меня, как это:

context.drawImage(video, 0, 0); 
video.addEventListener('canplaythrough', function() { 
    context.drawImage(video, 0, 0); 
}); 
Смежные вопросы