Я уже некоторое время бьюсь головой о проблеме.
Я работаю над детской игрой (flash as3), в которой ребенку читают рассказы, стихи, песни и т. Д. Есть голосовая запись чтения / пения текста, текст выделяется, когда слова произносятся / поются. Ребенок может самостоятельно включать и выключать подсветку голоса и слова. Ребенок также может сделать собственную запись. Сейчас говорит, что запись работает нормально. Я могу снять его с микрофона, и ребенок может воспроизвести его без проблем.
Проблема заключается в том, что клиент хочет, чтобы ребенок мог сохранить эту запись на веб-сервере.
Мне показалось, что проблема решена с помощью объекта URLRequest и URLLoader. MP3 обнаруживался в указанной папке на веб-сервере. Я играл в нее с помощью медиаплеера, и это сработало. Ребенок также может загрузить указанный файл без проблем.
ТОГДА, когда я попробовал это через браузер (вместо флеш-плеера), я получил страшную ошибку песочницы. Единственный способ, которым такая операция с указанными объектами может происходить в среде браузера, - это если пользователь инициируется через диалоговое окно. Об этом говорили дети, и мы все равно не экономим на месте.
Ребенку предоставляется 3 слота сохранения, по которым они щелкают (WSprites). Что технически инициируется пользователем, но Flash не может этого знать. 3 слота сохранения содержат звуки в памяти и изменяются только тогда, когда пользователь записывает или загружает. Когда пользователь сохраняет, его отправляют на php для сохранения.
Теперь я попытался использовать js в качестве посредника, но в итоге я потерял свои байты, и мои js и php, вероятно, самые слабые области всех моих навыков программирования.
У меня вопрос: знает ли кто-нибудь способ отправки байтового массива в php без установки песочницы. (желательно без JS, но если мне нужно, я должен)
Ниже приведен скрипт php:
<?php
$default_path = 'images/';
// check to see if a path was sent in from flash //
$target_path = ($_POST['dir']) ? $_POST['dir'] : $default_path;
if (!file_exists($target_path)) mkdir($target_path, 0777, true);
// full path to the saved image including filename //
$destination = $target_path . basename( $_FILES[ 'Filedata' ][ 'name' ] );
// move the image into the specified directory //
if (move_uploaded_file($_FILES[ 'Filedata' ][ 'tmp_name' ], $destination)) {
echo "The file " . basename( $_FILES[ 'Filedata' ][ 'name' ] ) . " has been uploaded;";
} else {
echo "FILE UPLOAD FAILED";
}
?>
Ниже приведен метод as3, который взаимодействует с ним:
public function save(slotNum:uint, byteArray:ByteArray, fileName:String,
$destination:String = null, $script:String=null,
parameters:Object = null):void
{
//trace("this happens"); //debug
_curRecordSlot = slotNum; //set slot number
_recorder = _recordSlots[_curRecordSlot]; //set recorder to new slot
_saveFileName = "recording" + _curRecordSlot.toString() + ".mp3"; //set recording file name
var i: int;
var bytes:String;
var postData:ByteArray = new ByteArray();
postData.endian = Endian.BIG_ENDIAN;
var ldr:URLLoader = new URLLoader(); //instantiate a url loader
ldr.dataFormat = URLLoaderDataFormat.BINARY; //set loader format
_request = new URLRequest(); //reinstantiate request
_request.url = $script; //set path to upload script
//add Filename to parameters
if (parameters == null)
{
parameters = new Object();
}
parameters.Filename = fileName;
//add parameters to postData
for (var name:String in parameters)
{
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="' + name + '"';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeUTFBytes(parameters[name]);
postData = LINEBREAK(postData);
}
//add img destination directory to postData if provided //
if ($destination)
{
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="dir"';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeUTFBytes($destination);
postData = LINEBREAK(postData);
}
//add Filedata to postData
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="Filedata"; filename="';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData.writeUTFBytes(fileName);
postData = QUOTATIONMARK(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Type: application/octet-stream';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
postData.writeBytes(byteArray, 0, byteArray.length);
postData = LINEBREAK(postData);
//add upload file to postData
postData = LINEBREAK(postData);
postData = BOUNDARY(postData);
postData = LINEBREAK(postData);
bytes = 'Content-Disposition: form-data; name="Upload"';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
postData = LINEBREAK(postData);
bytes = 'Submit Query';
for ( i = 0; i < bytes.length; i++ )
{
postData.writeByte( bytes.charCodeAt(i) );
}
postData = LINEBREAK(postData);
//closing boundary
postData = BOUNDARY(postData);
postData = DOUBLEDASH(postData);
//finally set up the urlrequest object //
_request.data = postData;
_request.contentType = 'multipart/form-data; boundary=' + _boundary;
_request.method = URLRequestMethod.POST;
_request.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
//add listener to listen for completion
ldr.addEventListener(Event.COMPLETE, onSaveComplete, false, 0, true);
//add listener for io errors
ldr.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
//add listener for security errors
ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError, false,
0, true);
ldr.load(_request); //load the file
}
Приведенный выше код прекрасно работает во флеш-плеере, но вызывает ошибку песочницы в браузере.
Edit:
В соответствии с моей просьбой, вот мой код для встраивания (я заменил любое место с названием игры на TITLEOFGAME):
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>TITLEOFGAME</title>
<meta name="description" content="" />
<script src="js/swfobject.js"></script>
<script>
var flashvars = {
};
var params = {
menu: "false",
scale: "noScale",
allowFullscreen: "true",
allowScriptAccess: "always",
bgcolor: "",
wmode: "direct" // can cause issues with FP settings & webcam
};
var attributes = {
id:"TITLEOFGAME"
};
swfobject.embedSWF(
"Hub.swf",
"altContent", "900", "506", "10.0.0",
"expressInstall.swf",
flashvars, params, attributes,
{name:"TITLEOFGAME"}
);
</script>
<style>
html, body { height:100%; overflow:hidden; }
body { margin:0; }
</style>
</head>
<body>
<div id="altContent">
<h1>TITLEOFGAME</h1>
<p><a href="http://www.adobe.com/go/getflashplayer">Get Adobe Flash
player</a></p> //this line was just moved down for limitations text input for
//this post
</div>
</body>
</html>