JavaScript でファイルを送るのに、jQuery.upload というプラグインを使用しているのですが、Moodle 上の、SCORM コンテンツの中で利用できません。SCORM コンテンツは iframe タグの中に表示されるのですが、何が良くないのか,うまく動かない。それで色々と調べている時に、ローカルのファイルの利用の仕方に関する記事を読みました。そこで,方針を変更してプラグインなしの方法を考えてみました。下記にupload用の例をあげます。冒頭のキャプチャー画像のソースです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Upload Sample</title>
<script type="text/javascript" src="jquery/jquery.min.js"></script>
<!-- クロスドメイン -->
<script src="jquery/xdr.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
$(function() {
$('#ifName').change(function() {
var target = document.getElementById('videoFrame');
var movie = this.files[0];
var reader = new FileReader();
reader.onloadend = function(){
target.src = reader.result;
var formData = new FormData();
formData.append('base64data', reader.result);
$.ajax({
url:'upload_base64.php?',
type:'post',
data:formData,
timeout:600000,
processData: false,
contentType: false,
success:function(tmptext,status){
alert(tmptext);
},
error:function(){
alert("upload error");
}
});
}; // reader.onloadend
if (movie) {
reader.readAsDataURL(movie);
} else {
target.src = '';
}
});
});
</script>
<input id="ifName" type="file" name="file" style="font-size:13px; height:24px; width:270px; background-color:#ffffff;" >
<video id="videoFrame" playsinline autoplay controls style="width: 480px; max-height:360px; background-color:#f0f0f0;"></video>
</body>
</html>
ifName という input タグで、ローカルの動画ファイルを選んで、 FileReader オブジェクトで読み込みます。読み込みが完了したら(onloadend)、読み込んだ結果(result)を video タグの src 属性に指定します。これで、動画が再生されます。この result とは 何かというと base64 にエンコードされたテキストデータです。テキストデータであれば、送信するときに特別なことは必要ありません。いつもの送信のやり方で送信できます。下記が受ける方の PHP です。クロスドメイン用のヘッダーが付いています。
<?php
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Headers:*');
header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
header('Content-Type: text/plain');
$base64data = $_POST['base64data'];
$base64data = str_replace(' ', '+', $base64data);
$tmpary = explode('base64,', $base64data);
$movie = base64_decode($tmpary[1]);
$tmpfile = fopen("./temporary/tmpfile","w");
fwrite($tmpfile,$movie);
fclose($tmpfile);
echo 'success';
?>
base64_decode() がかなりメモリーを必要とします。200MB の動画で、1000MB 程度のメモリーを必要とします。PHP へのメモリーの割当を増やして対応しましたが、どちらかというと JavaScript 側で、base64 をバイナリーファイルに変換したほうが良いと思います。あとで検討してみます。