关于 actionscript 3:as3/php mp3 字节数组传输和写入

as3/php mp3 byte array transport and write

我一直在纠结一个问题。

我正在开发一款 children 游戏(flash as3),可以向孩子朗读故事、诗歌、歌曲等内容。有一个语音记录阅读/演唱文本,当说出/唱出单词时,文本会突出显示。孩子可以独立打开和关闭语音和单词突出显示。孩子也可以选择制作自己的录音。现在说录音工作正常。我能够从麦克风中捕捉到它,孩子们可以毫无问题地播放它。

问题在于客户希望孩子能够将此录音保存到网络服务器。

我以为我通过使用 URLRequest 和 URLLoader 对象解决了这个问题。 mp3 显示在网络服务器上的指定文件夹中。我用媒体播放器播放了它,它奏效了。孩子也可以加载上述文件没问题。

然后,当我通过浏览器(而不是 Flash 播放器)尝试它时,我遇到了可怕的沙箱错误。在浏览器环境中对所述对象进行此类操作的唯一方式是用户通过对话窗口启动。这是孩子们在谈论的,无论如何我们都不会在本地储蓄。

为孩子提供了 3 个他们点击的保存位置 (WSprites)。从技术上讲,哪个是用户发起的,但 Flash 无法知道这一点。 3 个保存槽将声音保存在内存中,仅在用户录制或加载时更改。当用户保存时,他们会被发送到 php 进行保存。

现在我确实尝试使用 js 作为中间人,但我最终在这个过程中丢失了我的字节,我的 js 和 php 可能是我所有编程技能中最薄弱的领域。

我的问题是,有没有人知道一种在不启动沙箱的情况下将字节数组发送到 php 的方法。 (最好没有 js,但如果我必须,我必须)

下面是php脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
}

以上代码在 Flash Player 中运行良好,但在浏览器中触发沙箱错误。

编辑:

这里要求的是我的嵌入代码(我用 TITLEOFGAME 替换了任何有游戏名称的地方):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<html lang="en">
<head>
<meta charset="utf-8"/>
TITLEOFGAME
<meta name="description" content="" />

<script src="js/swfobject.js">

    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"}
    );
       

<style>
    html, body { height:100%; overflow:hidden; }
    body { margin:0; }
</style>
</head>
<body>

    TITLEOFGAME
    <p>Get Adobe Flash
                player</p> //this line was just moved down for limitations text input for
                               //this post

</body>
</html>


n


您可以将记录的数据作为字节数组发送到服务器端应用程序,字节 aaray 将按照所需的格式保存,如 flv 或任何其他文件(仅支持的格式)。请检查 AMFPHP、PHP 和使用 PHP 保存的字节数组