0 Votes

Wiki source code of Uncategorized Videos

Version 493.1 by Ryan C on 2025/09/10 03:49

Show last authors
1 {{velocity}}
2 ## Collect video attachments on the current page (safe getters only)
3 #set($videoExtensions = ['mp4','webm','ogg','avi','mov','wmv','flv','m4v'])
4 #set($videos = [])
5 #foreach($att in $doc.getAttachmentList())
6 #set($name = $att.getFilename())
7 #set($lname = $name.toLowerCase())
8 #foreach($ext in $videoExtensions)
9 #if($lname.endsWith("." + $ext))
10 #set($discard = $videos.add($att))
11 #break
12 #end
13 #end
14 #end
15
16 #if($videos.size() > 0)
17 {{html wiki="false" clean="false"}}
18 <div id="xwiki-video-manager" style="margin:20px 0;">
19 <h2>📹 Video Manager for: ${escapetool.xml($doc.fullName)}</h2>
20
21 <!-- Management panel only in edit action -->
22 #if($xcontext.action == 'edit')
23 <div class="video-management-panel" style="background:#f8f9fa;border:1px solid #dee2e6;border-radius:8px;padding:15px;margin-bottom:20px;">
24 <h3>🛠️ Video Management</h3>
25 <div style="margin-bottom:10px;">
26 <button onclick="toggleVideoManager()" class="btn btn-primary">Manage Videos</button>
27 <button onclick="exportVideoList()" class="btn btn-secondary">Export Video List</button>
28 </div>
29 <div id="video-manager-controls" style="display:none;">
30 <h4>Move Videos to Another Page:</h4>
31 <input type="text" id="target-page" placeholder="Space.PageName" style="width:300px;margin-right:10px;">
32 <button onclick="moveSelectedVideos()" class="btn btn-warning">Move Selected</button>
33 <div style="margin-top:10px;font-size:12px;color:#666;">
34 Select videos below and enter target page (e.g., "Main.MyPage")
35 </div>
36 </div>
37 </div>
38 #end
39
40 <!-- Display grid -->
41 <div class="video-display-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(400px,1fr));gap:20px;">
42 #set($i = 0)
43 #foreach($att in $videos)
44 #set($i = $i + 1)
45 #set($filename = $att.getFilename())
46 #set($lname = $filename.toLowerCase())
47 #set($url = $doc.getAttachmentURL($filename))
48 #set($vid = "video_${i}")
49
50 ## MIME type from extension (basic)
51 #set($videoType = "video/mp4")
52 #if($lname.endsWith(".webm"))
53 #set($videoType = "video/webm")
54 #elseif($lname.endsWith(".ogg"))
55 #set($videoType = "video/ogg")
56 #elseif($lname.endsWith(".avi"))
57 #set($videoType = "video/x-msvideo")
58 #elseif($lname.endsWith(".mov"))
59 #set($videoType = "video/quicktime")
60 #elseif($lname.endsWith(".wmv"))
61 #set($videoType = "video/x-ms-wmv")
62 #elseif($lname.endsWith(".flv"))
63 #set($videoType = "video/x-flv")
64 #elseif($lname.endsWith(".m4v"))
65 #set($videoType = "video/mp4")
66 #end
67
68 <div class="video-container" style="border:1px solid #ddd;border-radius:8px;padding:15px;background:#fff;">
69 <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
70 <h4 style="margin:0;flex-grow:1;">${escapetool.xml($filename)}</h4>
71 #if($xcontext.action == 'edit')
72 <input type="checkbox" class="video-selector" data-video="${escapetool.xml($filename)}" style="margin-left:10px;">
73 #end
74 </div>
75
76 <video id="${vid}" controls preload="metadata" style="width:100%;max-width:100%;border-radius:4px;">
77 <source src="${url}" type="${videoType}">
78 Your browser does not support the video tag.
79 </video>
80
81 <div class="video-controls" style="margin-top:10px;display:flex;flex-wrap:wrap;gap:5px;">
82 <button onclick="playPause('${vid}')" class="btn btn-sm btn-primary">⏯️ Play/Pause</button>
83 <button onclick="skipTime('${vid}', -10)" class="btn btn-sm btn-secondary">⏪ -10s</button>
84 <button onclick="skipTime('${vid}', 10)" class="btn btn-sm btn-secondary">⏩ +10s</button>
85 <button onclick="changeSpeed('${vid}', 0.5)" class="btn btn-sm btn-info">0.5x</button>
86 <button onclick="changeSpeed('${vid}', 1)" class="btn btn-sm btn-info">1x</button>
87 <button onclick="changeSpeed('${vid}', 1.5)" class="btn btn-sm btn-info">1.5x</button>
88 <button onclick="changeSpeed('${vid}', 2)" class="btn btn-sm btn-info">2x</button>
89 <a href="${url}" download="${escapetool.xml($filename)}" class="btn btn-sm btn-success">📥 Download</a>
90 </div>
91
92 <div class="video-info" style="margin-top:10px;font-size:12px;color:#666;">
93 <div>Size: $att.getLongSize() bytes</div>
94 <div>Modified: $xwiki.formatDate($att.getDate())</div>
95 <div id="${vid}_duration">Duration: Loading...</div>
96 </div>
97 </div>
98 #end
99 </div>
100 </div>
101
102 <script>
103 function playPause(id){const v=document.getElementById(id);if(v){v.paused?v.play():v.pause();}}
104 function skipTime(id,s){const v=document.getElementById(id);if(v){v.currentTime+=s;}}
105 function changeSpeed(id,sp){const v=document.getElementById(id);if(v){v.playbackRate=sp;}}
106 document.addEventListener('DOMContentLoaded',function(){
107 document.querySelectorAll('video').forEach(function(v){
108 v.addEventListener('loadedmetadata',function(){
109 var d=Math.round(v.duration)||0,m=Math.floor(d/60),s=d%60;
110 var e=document.getElementById(v.id+'_duration');
111 if(e){e.textContent='Duration: '+m+':' + String(s).padStart(2,'0');}
112 });
113 });
114 });
115 function toggleVideoManager(){
116 var c=document.getElementById('video-manager-controls');
117 if(c){c.style.display=(c.style.display==='none'||!c.style.display)?'block':'none';}
118 }
119 function moveSelectedVideos(){
120 const sel=[...document.querySelectorAll('.video-selector:checked')].map(x=>x.getAttribute('data-video'));
121 const target=(document.getElementById('target-page')||{}).value||'';
122 if(!target){alert('Please enter a target page (e.g., "Main.MyPage")');return;}
123 if(!sel.length){alert('Please select at least one video to move.');return;}
124 if(confirm('Move '+sel.length+' video(s) to '+target+'?\n\nVideos: '+sel.join(', '))){
125 alert('Server-side move not implemented.\nSelected: '+sel.join(', ')+'\nTarget: '+target);
126 }
127 }
128 function exportVideoList(){
129 const titles=[...document.querySelectorAll('.video-container h4')].map(h=>h.textContent);
130 const txt='Video List from '+window.location.href+'\n\n'+titles.join('\n');
131 const blob=new Blob([txt],{type:'text/plain'});const url=URL.createObjectURL(blob);
132 const a=document.createElement('a');a.href=url;a.download='video-list.txt';
133 document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(url);
134 }
135 document.addEventListener('keydown',function(e){
136 const v=document.querySelector('video:hover, video:focus'); if(!v) return;
137 switch(e.code){
138 case 'Space': e.preventDefault(); v.paused?v.play():v.pause(); break;
139 case 'ArrowLeft': e.preventDefault(); v.currentTime-=10; break;
140 case 'ArrowRight': e.preventDefault(); v.currentTime+=10; break;
141 }
142 });
143 </script>
144
145 <style>
146 .video-container:hover{box-shadow:0 4px 8px rgba(0,0,0,0.1);transition:box-shadow .3s ease;}
147 .btn{padding:4px 8px;border:1px solid #ddd;background:#f8f9fa;border-radius:4px;cursor:pointer;text-decoration:none;display:inline-block;}
148 .btn:hover{background:#e9ecef;}
149 .btn-primary{background:#007bff;color:#fff;border-color:#007bff;}
150 .btn-secondary{background:#6c757d;color:#fff;border-color:#6c757d;}
151 .btn-success{background:#28a745;color:#fff;border-color:#28a745;}
152 .btn-warning{background:#ffc107;color:#212529;border-color:#ffc107;}
153 .btn-info{background:#17a2b8;color:#fff;border-color:#17a2b8;}
154 .btn-sm{font-size:12px;padding:2px 6px;}
155 @media (max-width:768px){.video-display-grid{grid-template-columns:1fr}.video-controls{justify-content:center}}
156 </style>
157 {{/html}}
158 #else
159 {{html wiki="false" clean="false"}}
160 <div style="text-align:center;padding:40px;background:#f8f9fa;border-radius:8px;">
161 <h3>📹 No Videos Found</h3>
162 <p>No video files are attached to this page.</p>
163 #if($xcontext.action == 'edit')
164 <p>You can upload video files using the attachment feature in XWiki.</p>
165 #end
166 </div>
167 {{/html}}
168 #end
169 {{/velocity}}