it-swarm.com.de

Hinzufügen eines Elements zur Medienbibliothek über Blob oder DataUrl

Ich versuche, einen Webcam-Schnappschuss-Rekorder zu bauen. Es sollte ein Bild aufnehmen und über Ajax/Async-Upload in die Medienbibliothek WP hochladen.

Es wurde bereits eine Ansicht zur Medienbibliothek hinzugefügt. Die Aufnahme funktioniert auch. Ich kann die rohen Bilddaten entweder in einem Blob oder in einer Base 64-codierten Zeichenfolge (wie eine Daten-URL) speichern.

Wie kann ich diese Daten in die Upload-Warteschlange stellen?

Jeder Vorschlag/weitere Lektüre/gut erläuterte Gründe, warum dies nicht funktioniert, wird geschätzt.

Vielen dank joern

EDIT: Dies ist mein Code bisher. Es

  • fügt der Medienbibliothek WP ein Bedienfeld hinzu.

  • zeigt ein Bild mit src="data:image/ an

  • Versucht, ein dateiähnliches Objekt zu generieren und in die Upload-Warteschlange zu stellen. (Das ist, wo ich versage)

JS-Abhängigkeit: Benötigt Github Repo Blueimp/JavaScript-Canvas-to-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>
2
Jörn Lund

Endlich habe ich selbst eine Lösung gefunden.

Es gibt keine direkte Möglichkeit, reine Binärdaten (wie ein Blob) an das Upload-Objekt WP zu übergeben. Es werden nur dateibasierte Objekte verarbeitet. Ich musste eine separate XmlHttpRequest erstellen. (Die einfache Verwendung von $.ajax() hat nicht funktioniert und zu verunreinigten Bilddaten geführt.)

Nach dem erfolgreichen Hochladen der Bilddaten auf async-upload.php konnte ich ein 'FileUploaded'-Ereignis auslösen, zusammen mit der Antwort des Servers. Danach wurde das Bild in der Medienbibliothek angezeigt.

Das obige Codebeispiel könnte so aussehen (ungetestet und immer noch lückenhaft):

<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>

Die Funktion send_b64_data( b64data , filename , post_data , success_callback ) würde folgendermaßen aussehen:

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(send_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);
    }
}

Der Arbeitscode ist hier zu finden: https://github.com/mcguffin/say-cheese (WP-Plugin zum Hinzufügen von Webcam-Schnappschüssen und eingefügten Bildern zur MediaLibrary)

4
Jörn Lund