将项目从Blob或dataUrl添加到媒体库

时间:2014-01-16 作者:Jörn Lund

我正在尝试构建一个网络摄像头快照记录器。它应该拍摄一张照片并通过ajax/异步上传将其上传到WP媒体库。

已成功将视图添加到媒体库。录音也很有效。我可以将原始图像数据存储在blob中,也可以存储在base 64编码字符串中(如数据url)

如何将此数据放入上载队列?

任何建议/进一步阅读/解释清楚这不起作用的原因,我们将不胜感激。

非常感谢joern

编辑:这是到目前为止我的代码。信息技术

将面板添加到WP媒体库。

  • 显示带有src="data:image/

  • 尝试生成类似文件的对象并将其放入上载队列。(这就是我失败的地方)

  • JS依赖关系:需要github repo blueimp/JavaScript画布来Blob

    <script type="text/javascript">
    (function($){
    var media = wp.media,
        l10n = media.view.l10n = typeof _wpMediaViewsL10n === \'undefined\' ? {} : _wpMediaViewsL10n;
    
    // override router creation
    media.view.MediaFrame.Post.prototype.browseRouter = function( view ) {
        view.set({
            upload: {
                text:     l10n.uploadFilesTitle,
                priority: 20
            },
            dataurltest: {
                text:     \'DataUrl Test\', 
                priority: 30
            },
            browse: {
                text:     l10n.mediaLibraryTitle,
                priority: 40
            }
        });
    };
    
    var bindHandlers = media.view.MediaFrame.Post.prototype.bindHandlers,
        dataUrlTest, frame;
    
    media.view.MediaFrame.Post.prototype.bindHandlers = function() {
        // bind parent object handlers
        bindHandlers.apply( this, arguments );
        // bind our create handler.
        this.on( \'content:create:dataurltest\', this.dataurltestContent, this );
        frame = this;
    };
    media.view.MediaFrame.Post.prototype.dataurltestContent = function( content ){
        // generate test content
        var state = this.state();
        this.$el.removeClass(\'hide-toolbar\');
        dataUrlTest = new media.view.dataUrlTest({});
        content.view = dataUrlTest;
    }
    
    
    media.view.dataUrlTest = media.View.extend({
        // our test view
        tagName:   \'div\',
        className: \'data-url-test\',
    
        initialize: function() {
            _.defaults( this.options, {
    
            });
            var self = this, 
                blob;
    
    
            // add image with data-url to panel content
            var b64Data = \'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6\' +
                    \'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE\' +
                    \'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7\',
                imageUrl = \'data:image/gif;base64,\' + b64Data,
                $img = $(\'<img src="\'+imageUrl+\'" />\')
                    .appendTo(this.$el);
            // add a submit link
            $(\'<a href="#" class="test-send">Okay</a>\')
                .insertAfter($img)
                .on(\'click\',null,function(){
                    // creating a blob would go like this:
                    //blob = window.dataURLtoBlob && window.dataURLtoBlob($img.get(0).src)
    
                    var file = new plupload.File(null,b64Data);
                    file.name = \'test.gif\';
                    file.id = \'id\'+(new Date()).getTime(); 
    
                    var attributes = _.extend({
                        file:      file,
                        uploading: true,
                        date:      new Date(),
                        filename:  \'test.gif\',
                        menuOrder: 0,
                        uploadedTo: wp.media.model.settings.post.id,
                        type : \'image\',
                        subtype : \'gif\'
                    }, _.pick( file, \'loaded\', \'size\', \'percent\' ) );
    
                    file.attachment = wp.media.model.Attachment.create( attributes );
                    wp.Uploader.queue.add(file.attachment);
                    frame.uploader.uploader.uploader.refresh();
                    frame.uploader.uploader.uploader.start();
                });
    
        },
    });
    
    return;
    
    
    
    
    })(jQuery);
    </script>
    

    1 个回复
    最合适的回答,由SO网友:Jörn Lund 整理而成

    最后,我自己找到了一个解决方案。

    没有直接的方法将纯二进制数据(如blob)传递给WP upload对象。仅处理基于文件的对象。我必须创建一个单独的XmlHttpRequest。(仅使用$.ajax() 不工作,导致图像数据被污染。)

    成功将图像数据上载到异步上载后。php I能够触发“FileUpload”事件,以及服务器的响应。之后,图像显示在媒体库中。

    上面的代码示例可能如下所示(未经测试,仍然很粗略):

    <script type="text/javascript">
    (function($){
    var media = wp.media,
        frame,
        l10n = media.view.l10n = typeof _wpMediaViewsL10n === \'undefined\' ? {} : _wpMediaViewsL10n;
    
    // override router creation
    media.view.MediaFrame.Post.prototype.browseRouter = function( view ) {
        view.set({
            upload: {
                text:     l10n.uploadFilesTitle,
                priority: 20
            },
            dataurltest: {
                text:     \'DataUrl Test\', 
                priority: 30
            },
            browse: {
                text:     l10n.mediaLibraryTitle,
                priority: 40
            }
        });
    };
    
    var bindHandlers = media.view.MediaFrame.Post.prototype.bindHandlers,
        dataUrlTest, frame;
    
    media.view.MediaFrame.Post.prototype.bindHandlers = function() {
        // bind parent object handlers
        bindHandlers.apply( this, arguments );
        // bind our create handler.
        this.on( \'content:create:dataurltest\', this.dataurltestContent, this );
        frame = this;
    };
    media.view.MediaFrame.Post.prototype.dataurltestContent = function( content ){
        // generate test content
        var state = this.state();
        this.$el.removeClass(\'hide-toolbar\');
        dataUrlTest = new media.view.dataUrlTest({});
        content.view = dataUrlTest;
    }
    
    
    media.view.dataUrlTest = media.View.extend({
        // our test view
        tagName:   \'div\',
        className: \'data-url-test\',
    
        initialize: function() {
            _.defaults( this.options, {
    
            });
            var self = this, 
                blob;
    
            // add image with data-url to panel content
            var b64data =   \'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAGXRFWHRTb2Z0d2F\'+
                            \'yZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bX\'+
                            \'AAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTe\'+
                            \'k5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8i\'+
                            \'IHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjA\'+
                            \'xMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPS\'+
                            \'JodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gP\'+
                            \'HJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8v\'+
                            \'bnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmF\'+
                            \'kb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG\'+
                            \'9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yV\'+
                            \'G9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5z\'+
                            \'dGFuY2VJRD0ieG1wLmlpZDpGN0NENTMwNzdCNzcxMUUzQTBFQzg3RURFQTJCNTM\'+
                            \'5QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGN0NENTMwODdCNzcxMUUzQT\'+
                            \'BFQzg3RURFQTJCNTM5QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0Y\'+
                            \'W5jZUlEPSJ4bXAuaWlkOkY3Q0Q1MzA1N0I3NzExRTNBMEVDODdFREVBMkI1MzlC\'+
                            \'IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkY3Q0Q1MzA2N0I3NzExRTNBMEV\'+
                            \'DODdFREVBMkI1MzlCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+ID\'+
                            \'wveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+wqqcoQAAAAZQTFRFAAAA/\'+
                            \'///pdmf3QAAABFJREFUeNpiYBgFo4D6ACDAAAJYAAFvc4UPAAAAAElFTkSuQmCC\',
                imageUrl = \'data:image/png;base64,\' + b64data,
                $img = $(\'<img src="\'+imageUrl+\'" />\')
                    .appendTo(this.$el);
            // add a submit link
            $(\'<a href="#" class="test-send">Okay</a>\')
                .insertAfter($img)
                .on(\'click\',null,function(){
                    // creating a blob would go like this:
                    //blob = window.dataURLtoBlob && window.dataURLtoBlob($img.get(0).src)
    
                    // create and add item to upload queue
                    var file = {}; 
                    var attributes = {
                        file:      file,
                        uploading: true,
                        date:      new Date(),
                        filename:  \'test.png\',
                        menuOrder: 0,
                        uploadedTo: wp.media.model.settings.post.id,
                        type : \'image\',
                        subtype : \'png\',
                        loaded : 0,
                        size : 100,
                        percent : 0
                    };
    
                    file.attachment = wp.media.model.Attachment.create( attributes );
                    wp.Uploader.queue.add(file.attachment);
                
                    var post_data = {
                        action   : wp.Uploader.defaults.multipart_params.action,
                        _wpnonce : wp.Uploader.defaults.multipart_params._wpnonce,
                        post_id  : wp.media.model.settings.post.id
                    }
                
                     function upload_succes( xhr , httpStatus ) {
                        // this will update the uploaded image in the media library
                        frame.uploader.uploader.uploader.trigger(\'FileUploaded\', file, {
                            response : xhr.responseText,
                            status : httpStatus
                        });
                    }
               
                    send_b64_data( b64data , attributes.filename , post_data , upload_succes );
                });
    
        },
    });
    
    return;
    
    
    
    
    })(jQuery);
    </script>
    
    功能send_b64_data( b64data , filename , post_data , success_callback ) 看起来是这样的:

    function send_b64_data( b64data , filename , post_data , success_callback ) {
    
        var boundary, dashdash, crlf, multipart_string,
            file_data_name, name, mime_type , xhr;
        
        // setup multipart
        boundary            = \'----multipart_boundary\'+(new Date().getTime().toString(32))+Math.random().toString(32);
        dashdash            = \'--\';
        crlf                = \'\\r\\n\';
        
        
        // build request payload
        multipart_string    = \'\';
        for ( name in post_data ) {
            multipart_string += dashdash + boundary + crlf +
                \'Content-Disposition: form-data; name="\' + name + \'"\' + crlf + crlf;
            multipart_string += unescape(encodeURIComponent(post_data[name])) + crlf;
        }
        
        // add image data
        mime_type       = \'image/png\';
        file_data_name  = \'async-upload\';
        multipart_string += dashdash + boundary + crlf +
            \'Content-Disposition: form-data; name="\' + wp.Uploader.defaults.file_data_name + \'"; filename="\' + filename + \'"\' + crlf +
            \'Content-Type: \' + mime_type + crlf +
                crlf + atob( b64data ) + crlf +
                dashdash + boundary + dashdash + crlf;
        
        // build and send request
        xhr = new XMLHttpRequest()
        xhr.open("post", wp.Uploader.defaults.url, true);
        xhr.setRequestHeader(\'Content-Type\', \'multipart/form-data; boundary=\' + boundary);
        xhr.onreadystatechange = function() {
            var httpStatus, chunkArgs;
            if (xhr.readyState == 4 ) {
                try {
                    httpStatus = xhr.status;
                } catch (ex) {
                    httpStatus = 0;
                }
                if (httpStatus == 200) {
                    // will load contents to file fake
                    success_callback(xhr,httpStatus);
                } else if ( httpStatus >= 400 ) {
                    // handle error
                }
            }
        }
        
        if (xhr.sendAsBinary) { // Gecko
            xhr.sendAsBinary(multipart_string);
        } else { // WebKit with typed arrays support
            var ui8a = new Uint8Array(multipart_string.length);
            for (var i = 0; i < multipart_string.length; i++) {
                ui8a[i] = (multipart_string.charCodeAt(i) & 0xff);
            }
            xhr.send(ui8a.buffer);
        }
    }
    
    可在此处找到工作代码:https://github.com/mcguffin/say-cheese(WP插件允许您将网络摄像头快照和粘贴的图像添加到MediaLibrary)

    结束