WebCodecs api实现类似剪映视频剪辑软件代码
代码语言:html
所属分类:多媒体
代码描述:WebCodecs api实现类似剪映视频剪辑软件代码,纯前端js代码实现。
代码标签: WebCodecs api 类似 剪映 视频 剪辑 软件 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>WebCut Pro —— 基于 WebCodecs 的网页视频剪辑器</title>
<style>
:root{
--bg:#0d0e12; --panel:#14151b; --panel2:#1a1c24; --panel3:#22242f;
--line:#232634; --line2:#30344a;
--tx:#eceef6; --tx2:#8b90a5; --tx3:#5d6278;
--acc:#2fd4a2; --accHover:#27c293; --accSoft:rgba(47,212,162,.13);
--danger:#ff6b6b;
}
*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html,body{height:100%}
body{
background:var(--bg);color:var(--tx);
font:13px/1.6 -apple-system,"SF Pro Text","PingFang SC","Microsoft YaHei",system-ui,sans-serif;
display:flex;flex-direction:column;overflow:hidden;
-webkit-font-smoothing:antialiased;
}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--line2);border-radius:4px}
::-webkit-scrollbar-thumb:hover{background:#3d4260}
::-webkit-scrollbar-track{background:transparent}
button{
background:var(--panel2);color:var(--tx);border:1px solid var(--line);
border-radius:8px;padding:7px 14px;cursor:pointer;font-size:13px;font-weight:500;
transition:all .15s;font-family:inherit;
}
button:hover{background:var(--panel3);border-color:var(--line2)}
button.primary{background:linear-gradient(135deg,var(--acc),#1fb98a);border:none;color:#04241a;font-weight:700}
button.primary:hover{filter:brightness(1.1);background:linear-gradient(135deg,var(--acc),#1fb98a)}
button.danger{color:var(--danger);border-color:rgba(255,107,107,.25)}
button.danger:hover{background:rgba(255,107,107,.1);border-color:var(--danger)}
input[type=range]{accent-color:var(--acc)}
#topbar{height:54px;background:var(--panel);border-bottom:1px solid var(--line);
display:flex;align-items:center;gap:14px;padding:0 16px;flex:none}
.logo{font-size:16px;font-weight:700;letter-spacing:.3px;display:flex;align-items:center;gap:8px}
.logo .dot{width:9px;height:9px;border-radius:50%;background:var(--acc);box-shadow:0 0 10px var(--acc)}
.logo .pro{font-size:10px;font-weight:700;color:var(--acc);background:var(--accSoft);
padding:2px 7px;border-radius:20px;letter-spacing:.5px}
.logo .sub{font-size:11px;color:var(--tx3);font-weight:400}
.toolbar{display:flex;gap:8px;margin-left:auto}
main{flex:1;display:flex;min-height:0}
#library{width:238px;background:var(--panel);border-right:1px solid var(--line);
display:flex;flex-direction:column;flex:none}
.libHead{height:44px;display:flex;align-items:center;justify-content:space-between;
padding:0 12px;border-bottom:1px solid var(--line);flex:none}
.libHead b{font-size:13px;font-weight:600}
#libList{flex:1;overflow-y:auto;padding:10px}
.libEmpty{color:var(--tx3);text-align:center;padding:36px 8px;font-size:12px;line-height:2.1}
.libItem{display:flex;gap:9px;align-items:center;background:var(--panel2);
border:1px solid var(--line);border-radius:10px;padding:7px;margin-bottom:9px;
cursor:grab;position:relative;transition:all .15s}
.libItem:active{cursor:grabbing}
.libItem:hover{border-color:var(--line2);transform:translateY(-1px);box-shadow:0 4px 14px rgba(0,0,0,.35)}
.libThumb{width:70px;height:44px;border-radius:7px;background:#000;flex:none;
overflow:hidden;display:flex;align-items:center;justify-content:center;font-size:19px}
.libThumb img{width:100%;height:100%;object-fit:cover}
.libMeta{flex:1;min-width:0}
.libName{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.libSub{font-size:11px;color:var(--tx2);display:flex;align-items:center;gap:5px;margin-top:2px}
.badge{font-size:10px;padding:0 6px;border-radius:4px;line-height:16px;flex:none;font-weight:600}
.badge.video{background:rgba(92,140,255,.16);color:#8ab0ff}
.badge.audio{background:var(--accSoft);color:#5fe3bb}
.badge.image{background:rgba(190,140,255,.15);color:#cfaaff}
.libDel{position:absolute;top:3px;right:3px;width:18px;height:18px;padding:0;
font-size:12px;border:none;background:transparent;color:var(--tx3);opacity:0;line-height:1}
.libItem:hover .libDel{opacity:1}
.libDel:hover{color:var(--danger);background:transparent}
.libTip{padding:11px 13px;color:var(--tx3);font-size:11px;line-height:1.9;
border-top:1px solid var(--line);flex:none}
#previewArea{flex:1;display:flex;flex-direction:column;min-width:0}
#previewStage{flex:1;position:relative;background:#000;overflow:hidden}
#emptyTip{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
justify-content:center;color:var(--tx3);text-align:center;gap:7px;pointer-events:none;z-index:4}
#emptyTip small{opacity:.7;font-size:11px}
/* ---------- 主视频包装层(可变换) ---------- */
.vWrap{position:absolute;z-index:1;cursor:move;user-select:none;-webkit-user-select:none;touch-action:none}
.vWrap video{width:100%;height:100%;object-fit:fill;display:block}
/* ---------- 可视化元素(字幕/图片)交互层 ---------- */
.ovWrap{position:absolute;z-index:3;cursor:move;user-select:none;-webkit-user-select:none;touch-action:none}
.ovWrap img{display:block;width:100%;height:100%}
.ovWrap.subtitle{width:max-content}
.ovSubText{font-weight:700;white-space:pre-line;line-height:1.25;text-align:center;padding:2px 8px}
/* ---------- 通用选择框 & 手柄(视频/图片/字幕共用) ---------- */
.ovFrame{display:none;position:absolute;inset:-3px;border:1.5px solid var(--acc);
border-radius:2px;pointer-events:none}
.selected .ovFrame{display:block}
.ovFrame::before{content:'';position:absolute;left:50%;top:-21px;width:1.5px;height:18px;background:var(--acc)}
.ovHandle{position:absolute;width:11px;height:11px;background:#fff;border:2px solid var(--acc);
border-radius:50%;pointer-events:auto;box-sizing:border-box}
.ovHandle.nw{left:-6px;top:-6px;cursor:nwse-resize}
.ovHandle.ne{right:-6px;top:-6px;cursor:nesw-resize}
.ovHandle.sw{left:-6px;bottom:-6px;cursor:nesw-resize}
.ovHandle.se{right:-6px;bottom:-6px;cursor:nwse-resize}
.ovHandle.rot{left:50%;top:-32px;transform:translateX(-50%);cursor:grab;background:var(--acc)}
#transport{height:52px;background:var(--panel);border-top:1px solid var(--line);
display:flex;align-items:center;justify-content:center;gap:10px;padding:0 16px;flex:none;position:relative}
#transport button{width:36px;height:36px;padding:0;border-radius:50%;font-size:14px;
display:flex;align-items:center;justify-content:center}
#btnPlay{width:42px;height:42px;background:linear-gradient(135deg,var(--acc),#1fb98a);
border:none;color:#04241a;font-size:16px}
#btnPlay:hover{filter:brightness(1.1);background:linear-gradient(135deg,var(--acc),#1fb98a)}
.timeBox{position:absolute;right:16px;font-variant-numeric:tabular-nums;font-size:12px;letter-spacing:.3px}
#timeNow{color:var(--acc)}
#timeTotal{color:var(--tx3)}
#inspector{width:282px;background:var(--panel);border-left:1px solid var(--line);
padding:14px;overflow-y:auto;flex:none}
#inspector h3{font-size:13px;font-weight:600;margin-bottom:10px;color:var(--tx2);
text-transform:uppercase;letter-spacing:1px}
#noSel{color:var(--tx3);padding:30px 10px;text-align:center;font-size:12px;line-height:2}
.inspActions{display:flex;gap:8px;margin-bottom:16px}
.inspActions button{flex:1;font-size:12.5px}
.sec{margin:16px 0 8px;color:var(--tx3);font-size:10.5px;font-weight:600;
text-transform:uppercase;letter-spacing:1.2px;display:flex;align-items:center;gap:8px}
.sec::after{content:'';flex:1;height:1px;background:var(--line)}
#clipInfo{white-space:pre-line;color:var(--tx2);font-size:12px;background:var(--panel2);
border:1px solid var(--line);border-radius:8px;padding:9px 11px;word-break:break-all;line-height:1.7}
.frow{display:flex;align-items:center;gap:9px;margin:7px 0}
.frow .flab{width:46px;color:var(--tx2);flex:none;font-size:12px}
.frow input[type=range]{flex:1}
.frow .fval{width:54px;text-align:right;color:var(--acc);font-variant-numeric:tabular-nums;
flex:none;font-size:12px;font-weight:600}
#inspBody textarea{width:100%;height:76px;background:var(--panel2);color:var(--tx);
border:1px solid var(--line);border-radius:8px;padding:8px;resize:vertical;font-size:13px;
font-family:inherit;outline:none}
#inspBody textarea:focus{border-color:var(--acc)}
input[type=color]{width:46px;height:28px;padding:0;border:1px solid var(--line);
background:none;border-radius:6px;cursor:pointer}
#presetGrid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:8px 0}
#presetGrid button{padding:6px 2px;font-size:11.5px}
.wide{width:100%}
.help{margin-top:22px;color:var(--tx3);font-size:11px;line-height:1.9;
border-top:1px solid var(--line);padding-top:12px}
#timelineArea{height:232px;background:var(--panel);border-top:1px solid var(--line);
display:flex;flex-direction:column;flex:none;user-select:none}
#tlToolbar{height:40px;display:flex;align-items:center;gap:12px;padding:0 14px;
border-bottom:1px solid var(--line);color:var(--tx2);flex:none;font-size:12px}
#tlToolbar .spacer{flex:1}
#timelineScroll{flex:1;overflow-x:auto;overflow-y:hidden}
#timelineContent{position:relative;height:192px}
#ruler{display:block;height:26px;background:var(--panel2);cursor:pointer}
.lane.........完整代码请登录后点击上方下载按钮下载查看















网友评论0