Mediabunny实现浏览器中离线网页可视化剪辑视频声音文本图片时间轴轨道导出mp4视频代码

代码语言:html

所属分类:多媒体

代码描述:Mediabunny实现浏览器中离线网页可视化剪辑视频声音文本图片时间轴轨道导出mp4视频代码,可添加视频、图片、声音、文字字幕轨道并且可导入声音、视频、文字、图片素材,支持时间轴拖拽素材移动,入场出场动画,持续时间、分割视频、音频片段,删除素材,移动文字,最后混合时间轴导出mp4视频,全程离线在浏览器中实现。

代码标签: Mediabunny 浏览器 离线 网页 可视化 剪辑 视频 声音 文本 图片 时间轴 轨道 导出

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <title>可视化拖拽动画设计器(新建轨/指针插入/分割/静音 | Mediabunny)</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <style>
    :root{
      --bg:#0b1220; --panel:#111827; --muted:#94a3b8; --text:#e5e7eb;
      --accent:#06b6d4; --ok:#22c55e; --danger:#ef4444; --warn:#f59e0b;
      --border:rgba(148,163,184,.2); --clip-v:rgba(59,130,246,.22);
      --clip-t:rgba(245,158,11,.22); --clip-a:rgba(34,197,94,.22);
    }
    *{box-sizing:border-box}
    body{margin:0;background:linear-gradient(135deg,#0b1220,#0e1528 60%, #0b1220);color:var(--text);font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial}
    .container{max-width:1200px;margin:20px auto;padding:0 16px 80px}
    header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
    h1{font-size:18px;margin:0;color:#d1e9ff}
    .badge{padding:4px 8px;background:rgba(148,163,184,.12);border:1px solid rgba(148,163,184,.2);border-radius:999px;font-size:12px;color:#cbd5e1}
    .panel{background:rgba(17,24,39,.8);border:1px solid var(--border);border-radius:14px;padding:14px;margin-bottom:12px;backdrop-filter:blur(8px)}
    .row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
    .grow{flex:1}
    input[type="number"], input[type="text"], select{
      background:#0b1220;color:var(--text);border:1px solid rgba(148,163,184,.3);border-radius:10px;padding:8px 10px;outline:none;min-width:0
    }
    input[type="file"]{color:var(--text)}
    input[type="color"]{border:none;background:transparent}
    button{
      background:#0b1220;color:var(--text);border:1px solid rgba(148,163,184,.35);
      padding:8px 12px;border-radius:10px;cursor:pointer;transition:.15s;display:inline-flex;align-items:center;gap:6px
    }
    button:hover{border-color:var(--accent);box-shadow:0 0 0 2px rgba(6,182,212,.18) inset}
    button.primary{background:linear-gradient(135deg,#06b6d4,#3b82f6);border:none}
    button.success{background:linear-gradient(135deg,#22c55e,#16a34a);border:none}
    button.danger{background:linear-gradient(135deg,#ef4444,#f43f5e);border:none}
    button.warn{background:linear-gradient(135deg,#f59e0b,#f97316);border:none}
    button.ghost{background:transparent;border:1px dashed rgba(148,163,184,.35)}
    button:disabled{opacity:.6;cursor:not-allowed}
    .hint{font-size:12px;color:var(--muted)}
    progress{width:100%;height:14px;accent-color:var(--accent)}
    canvas{background:#000;border-radius:12px;border:1px solid var(--border);max-width:100%}

    .timeline-wrap{border:1px solid var(--border);border-radius:12px;overflow:hidden;background:rgba(0,0,0,.25)}
    .timeline-toolbar{display:flex;align-items:center;gap:10px;padding:8px;border-bottom:1px solid var(--border);flex-wrap:wrap}
    .toolbar-group{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
    .ruler{position:relative;height:24px;background:rgba(255,255,255,.04)}
    .tracks{position:relative;overflow:auto;max-height:420px}
    .track-row{display:flex;align-items:stretch;border-bottom:1px solid rgba(148,163,184,.14)}
    .track-label{width:140px;min-width:140px;border-right:1px solid rgba(148,163,184,.14);padding:6px;font-size:12px;color:#cbd5e1;cursor:pointer;user-select:none}
    .track-label.active{background:rgba(6,182,212,.18); border-right-color:rgba(6,182,212,.45); color:#9be8ff}
    .track-scroll{
      position:relative; flex:1; min-height:64px; background:
      repeating-linear-gradient(to right, rgba(255,255,255,.03) 0, rgba(255,255,255,.03) 1px, transparent 1px, transparent 10px),
      repeating-linear-gradient(to right, rgba(255,255,255,.06) 0, rgba(255,255,255,.06) 1px, transparent 1px, transparent 100px);
    }
    .track-scroll.drop-ok{outline:2px dashed rgba(6,182,212,.55); outline-offset:-4px}
    .clip{position:absolute;height:40px;border:1px solid var(--border);border-radius:8px;backdrop-filter:blur(1px);
      display:flex;align-items:center;gap:6px;padding:2px 8px 2px 8px;cursor:grab;user-select:none;overflow:hidden}
    .clip-visual{background:var(--clip-v)}
    .clip-text{background:var(--clip-t);height:30px;top:17px}
    .clip-audio{background:var(--clip-a)}
    .clip .name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:12px;color:#e5e7eb}
    .clip.selected{outline:2px solid #93c5fd}
    .clip .mini-btn{
      font-size:12px;padding:3px 8px;border-radius:8px;line-height:1;border:1px solid rgba(148,163,184,.35);
      background:rgba(148,163,184,.18); color:#e5e7eb; cursor:pointer;
    }
    .clip .mini-btn:hover{background:rgba(6,182,212,.25)}
    .clip.muted{opacity:0.85; border-style:dashed; filter:grayscale(0.2) brightness(0.95)}
    .handle{position:absolute;top:0;width:8px;height:100%;cursor:ew-resize;background:rgba(255,255,255,.15)}
    .handle.left{left:-2px;border-radius:6px 0 0 6px}
    .handle.right{right:-2px;border-radius:0 6px 6px 0}
    .playhead{position:absolute;top:0;width:2px;background:#ef4444;height:100%}
  </style>
</head>
<body>
  <div class="container">
    <header>
      <h1>🎨 可视化拖拽动画设计器(新建轨/指针插入/分割/静音)</h1>
      <div class="row" style="gap:8px">
        <span class="badge">视频/音频/文字多轨</span>
        <span class="badge">画布拖拽文本</span>
        <span class="badge">视频可静音</span>
        <span class="badge">MP4 导出</span>
      </div>
    </header>

    <div class="panel">
      <div class="row">
        <div class="grow">
          <strong>预览画布</strong>
          <div class="hint">可直接拖拽文本改变位置(当前时间点可见的文本)。如当前帧存在静音视频,会在左上角显示“🔇”。</div>
        </div>
        <div class="row">
          <label>宽</label><input id="wInput" type="number" min="256" step="2" value="1280" style="width:100px" />
          <label>高</label><input id="hInput" type="number" min="256" step="2" value="720" style="width:100px" />
          <label>FPS</label><input id="fpsInput" type="number" min="1" max="60" step="1" value="30" style="width:100px" />
          <label>适配</label>
          <select id="fitSel">
            <option value="cover" selected>cover</option>
            <option value="contain">contain</option>
            <option value="fill">fill</option>
          </select>
        </div>
      </div>
      <div style="margin-top:8px">
        <canvas id="canvas" width="1280" height="720"></canvas>
      </div>
    </div>

    <div class="panel timeline-wrap">
      <div class="timeline-toolbar">
        <div class="toolbar-group">
          <button id="addImageBtn" class="primary">🖼️ 添加图片</button>
          <input id="imageInput" type="file" accept="image/*" multiple style="display:none" />
          <button id="addVideoBtn" class="primary">🎬 添加视频</button>
          <input id="videoInput" type="file" accept="video/*" multiple style="display:none" />
          <button id="addTextBtn" class="warn">🅣 添加文本</button>
          <button id="addAudioBtn" class="primary">🎵 添加音频</button>
          <input id="audioInput" type="file" accept="audio/*" multiple style="display:none" />
        </div>
        <div class="toolbar-group">
          <button id="addVTrackBtn" class="ghost">➕ 新建视频轨</button>
          <button id="addATrackBtn" class="ghost">➕ 新建音频轨</button>
          <button id="addTTrackBtn" class="ghost">➕ 新建文字轨</button>
        </div>
        <div class="grow"></div>
        <div class="toolbar-group">
          <button id="splitBtn">✂️ 分割</button>
          <button id="deleteBtn" class="danger">🗑️ 删除选中</button>
          <label>缩放(px/s)</label>
          <input id="zoomRange" type=&.........完整代码请登录后点击上方下载按钮下载查看

网友评论0