有没有办法保存脏画布?

时间:2012-03-01 15:54:06

标签: image html5 video canvas

我正在制作带有HTML5画布的视频截图,视频在其他地方托管,除了toDataURL()之外一切正常,因为画布很脏。所以,我想知道,有什么办法可以在计算机上保存这个画布图像吗?

我认为答案是肯定的,但希望有一些黑客能够完成这项工作,除了将视频下载到我的服务器并从那里提供服务之外,还有任何想法......

3 个答案:

答案 0 :(得分:0)

简短的回答是“不。”

答案可能更长。

也许您的服务器可以下载视频并托管它,然后从同一个域播放它?

如果您控制托管视频的服务器,则可以enable cors

(或者您可以将两者合并,并将视频上传到不属于您自己的cors启用的网站。)

否则,你运气不好。

答案 1 :(得分:0)

如果你在另一个画布上重绘原始画布然后保存到图像,我还没有尝试过。 (并使用css或将画布彼此定位以“隐藏”第二个画布)。

第二幅帆布会变脏吗?

thinking about a technique like thisone

答案 2 :(得分:0)

我尝试了复制画布,但这只是返回了相同的脏画布错误。

为了完成这项工作,我实现了一个小服务,它将提取远程源(视频)并使它们看起来像是本地的,即通过阅读源服务器端并写出我的HTML / JS页面。一旦完成,一切正常。

我使用Python / Flask来做这个,这里是片段。在处理部分内容请求方面并不完美,但应该有人去。

要使用它,我使用以下方式访问我的视频:/ remote?url =

from datetime import timedelta
from flask import make_response, request, current_app, Flask, url_for, render_template, Response
from functools import update_wrapper
import requests
import logging
import json
from werkzeug.datastructures import Headers
import httplib
import os
import subprocess
import base64
httplib.HTTPConnection.debuglevel = 1

app = Flask(__name__)


logging.basicConfig() 
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

def crossdomain(origin=None, methods=None, headers=None,
                max_age=21600, attach_to_all=True,
                automatic_options=True):
    if methods is not None:
        methods = ', '.join(sorted(x.upper() for x in methods))
    if headers is not None and not isinstance(headers, basestring):
        headers = ', '.join(x.upper() for x in headers)
    if not isinstance(origin, basestring):
        origin = ', '.join(origin)
    if isinstance(max_age, timedelta):
        max_age = max_age.total_seconds()

    def get_methods():
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']

    def decorator(f):
        def wrapped_function(*args, **kwargs):
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers

            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp

        f.provide_automatic_options = False
        return update_wrapper(wrapped_function, f)
    return decorator

def stream_remote(url, headers=None):
    logging.debug(headers) 
    range = headers["Range"]
    logging.debug(range)
    r = requests.get(url, stream=True, headers={"range":range})
    logging.debug(r.headers)
    for block in r.iter_content(1024):
        if not block:
            break
        yield block


@app.route('/remote/')
def get_remote():
    # Gets a remote file to make it look like it is local for CORS purposes
    url = request.args.get("url", None)
    resp_headers = Headers()
    resp_headers.add('Accept-Ranges','bytes')

    if url is None:
        return "Error. No URL provided"
    else:
        headers = request.headers
        logging.debug(headers)
        return Response(stream_remote(url, headers),mimetype='video/mp4',headers=resp_headers)

if __name__ == '__main__':
    app.debug = True
    app.run(host="127.0.0.1", port=9001)