Skip to content

Commit 4d7f7eb

Browse files
committed
I'm crushing your head!
1 parent 86e610f commit 4d7f7eb

3 files changed

Lines changed: 175 additions & 49 deletions

File tree

apps/media/VideoCutter.js

Lines changed: 162 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/*9/9/25: 3 ways of referencing the time points in a video timeline:
2+
3+
1) floating point: this is the literal time value (no mark created)
4+
2) decimal: this is the mark's number in an array of anonymous marks
5+
3) symbolic: currently, only single (1 byte) alphabetic characters: a-zA-Z
6+
7+
The main question is whether the named marks are only in a hash map or are also in
8+
9+
*/
110
/*9/7/25: Need to seriously simplyfy the timeline positioning/rendering logic. Right now, «
211
there is an issue for when the timeline is wider than the window, and the time marker is at
312
the end. It seems that the timeline is positioned so that only a couple preview frames are
@@ -240,7 +249,8 @@ let clusters;
240249
let cluster_times = [];
241250
let cluster_time_marks;
242251

243-
let marks = [];
252+
let sym_marks = [];
253+
let pos_marks = [];
244254
//let mark_times
245255

246256
let min_time_wid=0;
@@ -415,7 +425,14 @@ const await_seek = (tm)=>{//«
415425
};//»
416426

417427
const handle_tab = k => {//«
418-
let m = find_next_of_arr(k, cur_mark, marks);
428+
429+
let all_marks = pos_marks.concat(sym_marks);
430+
all_marks = all_marks.sort((a,b)=>{
431+
if (a._time < b._time) return -1;
432+
return 1;
433+
});
434+
// let m = find_next_of_arr(k, cur_mark, sym_marks);
435+
let m = find_next_of_arr(k, cur_mark, all_marks);
419436
if (!m) return;
420437
if (cur_mark) {
421438
cur_mark._off();
@@ -469,7 +486,9 @@ const try_delete = async()=>{//«
469486
is_waiting = true;
470487
// await cur_mark._on();
471488
await seek_to_time(cur_mark._time);
472-
if (await wdg.popyesno(`Delete marker: '${cur_mark._id}'?`)){
489+
let use_id = cur_mark._id;
490+
if (isNum(use_id)) use_id++;
491+
if (await wdg.popyesno(`Delete marker: '${use_id}'?`)){
473492
cur_mark._delIt();
474493
}
475494
is_waiting = false;
@@ -926,7 +945,7 @@ const get_render_slices = (arr, errarg) => {//«
926945
const err = errarg || wdg.poperr;
927946

928947
let hash = {};
929-
for (let m of marks){
948+
for (let m of sym_marks){
930949
hash[m._id] = m;
931950
}
932951

@@ -994,8 +1013,8 @@ cwarn("No output");
9941013
is_waiting = false;
9951014
};//»
9961015

997-
const scroll_elem = (elem, tm, x_off)=>{//«
998-
let offset = get_timeline_offset(tm);
1016+
const scroll_elem = (elem, tm, x_off, bounds_start_arg)=>{//«
1017+
let offset = get_timeline_offset(tm, bounds_start_arg);
9991018
if (offset < -10||offset>Main._w+10) elem._dis = "none";
10001019
else{
10011020
elem._dis = "";
@@ -1130,7 +1149,7 @@ const handle_await_arrow_up=(k)=>{//«
11301149
cur_set_images = new SetTimelineImages();
11311150
}
11321151
let gotto = vid.currentTime + total_scroll;
1133-
if (gotto > viddur) gotto = viddur - 0.001;
1152+
if (gotto > viddur) gotto = viddur - 0.0001;
11341153
else if (gotto < 0) gotto = 0;
11351154
vid.currentTime = gotto;
11361155
tmdiv.innerHTML = get_main_time_str(gotto);
@@ -1358,15 +1377,22 @@ The video stays at the end.
13581377
const seek_to_end=async()=>{//«
13591378
timeline._xLoc = Main._w - timeline._width - GRID_W_HALF;
13601379
align_timeline();
1361-
await seek_to_time(viddur-0.001, true);
1380+
// await seek_to_time(viddur-0.001, true);
1381+
seek_to_time(viddur-0.0001, true);
13621382
draw_ruler({addLast:true});
13631383
};//»
13641384
const center_to_curtime = () => {//«
13651385
center_to_time(vid.currentTime);
13661386
};//»
1367-
const get_timeline_offset = tm => {//«
1368-
let bounds = get_visual_time_bounds();
1369-
let tmoff = tm - bounds.start;
1387+
const get_timeline_offset = (tm, bounds_start_arg) => {//«
1388+
let tmoff;
1389+
if (isNum(bounds_start_arg)){
1390+
tmoff = tm - bounds_start_arg;
1391+
}
1392+
else {
1393+
let bounds = get_visual_time_bounds();
1394+
tmoff = tm - bounds.start;
1395+
}
13701396
let peroff = tmoff / viddur;
13711397
return peroff * timeline._width;
13721398
};//»
@@ -1799,20 +1825,67 @@ check_timeline_right_edge_for_underflow_and_center_to_time(vid.currentTime);
17991825
};//»
18001826

18011827
const scroll_marks=()=>{//«
1802-
for (let m of marks){
1803-
scroll_elem(m, m._time, MARK_X_OFF);
1828+
// let bounds = get_visual_time_bounds();
1829+
let bounds_start = get_visual_time_bounds().start;
1830+
let all_marks = pos_marks.concat(sym_marks);
1831+
for (let m of all_marks){
1832+
// scroll_elem(m, m._time, MARK_X_OFF);
1833+
scroll_elem(m, m._time, MARK_X_OFF, bounds_start);
18041834
}
18051835
};//»
18061836
const seek_to_timeline_start=async()=>{//«
18071837
await await_seek(get_visual_time_bounds().start);
18081838
};//»
1839+
const try_seek_mark=async(if_popin)=>{//«
1840+
is_waiting = true;
1841+
let rv;
1842+
if (if_popin) rv = await wdg.popin(`Seek to mark?`);
1843+
// else rv = await wdg.popkey(`Seek to sym mark?`, {alpha: true});
1844+
else rv = await wdg.popkey(`Seek to mark?`, {alpha: true, digit: true});
1845+
if (rv) {
1846+
let gotit = false;
1847+
if (isNum(rv)){
1848+
rv = String.fromCharCode(rv);
1849+
}
1850+
if (rv.match(/^[a-zA-Z]$/)){
1851+
for (let mrk of sym_marks){
1852+
if (mrk._id == rv){
1853+
if (cur_mark) cur_mark._off();
1854+
gotit = true;
1855+
mrk._on();
1856+
break;
1857+
}
1858+
}
1859+
}
1860+
else if (rv.match(/^\d+$/)){
1861+
let id = parseInt(rv) - 1;
1862+
for (let mrk of pos_marks){
1863+
if (mrk._id == id){
1864+
if (cur_mark) cur_mark._off();
1865+
gotit = true;
1866+
mrk._on();
1867+
break;
1868+
}
1869+
}
1870+
}
1871+
else{
1872+
wdg.poperr(`Invalid mark id: ${rv}`);
1873+
gotit = true;
1874+
}
1875+
if (!gotit){
1876+
wdg.popup(`The mark does not exist: '${rv}'`);
1877+
}
1878+
}
1879+
is_waiting = false;
1880+
};//»
1881+
/*
18091882
const try_seek_mark=async()=>{//«
18101883
is_waiting = true;
1811-
let rv = await wdg.popkey(`Seek to marker?`, {alpha: true});
1884+
let rv = await wdg.popkey(`Seek to sym mark?`, {alpha: true});
18121885
if (rv) {
18131886
rv = String.fromCharCode(rv);
18141887
let nogo=false;
1815-
for (let mrk of marks){
1888+
for (let mrk of sym_marks){
18161889
if (mrk._id == rv){
18171890
if (cur_mark) cur_mark._off();
18181891
mrk._on();
@@ -1822,14 +1895,20 @@ const try_seek_mark=async()=>{//«
18221895
}
18231896
is_waiting = false;
18241897
};//»
1825-
const try_create_mark=async()=>{//«
1898+
*/
1899+
const try_create_mark=async(if_sym)=>{//«
1900+
if (!if_sym){
1901+
if (cur_mark) cur_mark._off();
1902+
create_mark(vid.currentTime);
1903+
return;
1904+
}
18261905
is_waiting = true;
18271906
let rv = await wdg.popkey(`New marker id?`, {alpha: true});
18281907
//log(rv);
18291908
if (rv) {
18301909
rv = String.fromCharCode(rv);
18311910
let nogo=false;
1832-
for (let mrk of marks){
1911+
for (let mrk of sym_marks){
18331912
if (mrk._id == rv){
18341913
nogo = true;
18351914
wdg.poperr(`Another mark with id '${rv}' exists!`);
@@ -1843,29 +1922,45 @@ const try_create_mark=async()=>{//«
18431922
}
18441923
is_waiting = false;
18451924
};//»
1925+
const renumber_pos_marks = ()=> {
1926+
for (let i=0; i < pos_marks.length; i++){
1927+
let m = pos_marks[i];
1928+
m._id = i;
1929+
m.innerHTML = i+1;
1930+
}
1931+
}
18461932
const create_mark=(usetime, id, if_auto)=>{//«
18471933
let tm = usetime || vid.currentTime;
1848-
for (let m of marks){
1934+
let all_marks = pos_marks.concat(sym_marks);
1935+
// for (let m of sym_marks){
1936+
for (let m of all_marks){
18491937
let diff = Math.abs(m._time - tm);
18501938
if (diff < MARK_DIFF_THRESH){
18511939
wdg.poperr(`Another mark is too close (${diff} < ${MARK_DIFF_THRESH})`);
18521940
return;
18531941
}
18541942
}
1943+
let mark_pos;
1944+
if (!id){
1945+
id = 0;
1946+
for (let m of pos_marks){
1947+
//cwarn(tm, m._time);
1948+
if (tm < m._time){
1949+
break;
1950+
}
1951+
id++;
1952+
}
1953+
//log("ID",id);
1954+
}
18551955
let mrk = mkdv();
18561956
mrk._pos="absolute";
1857-
// mrk._tcol="#000";
1858-
// mrk.innerHTML='v';
1859-
mrk.innerHTML=id;
1957+
mrk.innerHTML = id;
1958+
mrk._id = id;
18601959
mrk._fs = MARK_SZ;
18611960
mrk._y = MARK_Y;
1862-
// mrk._fw=900;
18631961
mrk.setAttribute("name","marker");
18641962
mrk._z = 100;
18651963
mrk._time = tm;
1866-
mrk._id = id;
1867-
//log(mrk);
1868-
// mrk._tcol=MARK_OFF_COL;
18691964
mrk._off = ()=>{
18701965
mrk._tcol=MARK_OFF_COL;
18711966
mrk._fw="";
@@ -1879,34 +1974,51 @@ const create_mark=(usetime, id, if_auto)=>{//«
18791974
center_to_curtime();
18801975
scroll_marks();
18811976
scroll_cluster_marks();
1882-
stat(`Current mark: '${id}' (${tm.toFixed(3)}s)`);
1977+
if (isNum(id)) stat(`Pos mark: #${mrk._id+1} (${tm.toFixed(3)}s)`);
1978+
else stat(`Sym mark: '${mrk._id}' (${tm.toFixed(3)}s)`);
18831979
};
18841980
mrk._delIt = ()=>{
1885-
remove_elem(mrk, marks);
1981+
if (isNum(id)){
1982+
remove_elem(mrk, pos_marks);
1983+
renumber_pos_marks();
1984+
}
1985+
else {
1986+
remove_elem(mrk, sym_marks);
1987+
}
1988+
if (isNum(id)) stat(`Deleted: #${mrk._id+1}`);
1989+
else stat(`Deleted: '${mrk._id}'`);
18861990
mrk._del();
1887-
if (marks.length) marks[0]._on();
1991+
cur_mark = null;
18881992
};
18891993
if (cur_mark) cur_mark._off();
18901994
mrk._maybeScroll = ()=>{
18911995
check_scroll(mrk);
18921996
}
18931997
if (if_auto) mrk._off();
18941998
else mrk._on();
1895-
18961999
timeline._add(mrk);
1897-
marks.push(mrk);
1898-
marks = marks.sort((a,b)=>{
1899-
if (a._time < b._time) return -1;
1900-
return 1;
1901-
});
2000+
2001+
if (isNum(id)){
2002+
pos_marks.splice(id, 0, mrk);
2003+
renumber_pos_marks();
2004+
}
2005+
else {
2006+
sym_marks.push(mrk);
2007+
sym_marks = sym_marks.sort((a,b)=>{
2008+
if (a._time < b._time) return -1;
2009+
return 1;
2010+
});
2011+
}
2012+
19022013
scroll_marks();
19032014
scroll_cluster_marks();
19042015
};//»
19052016

19062017
const scroll_cluster_marks=()=>{//«
19072018
if (cluster_marks_div._dis=="none") return;
2019+
let bounds_start = get_visual_time_bounds().start;
19082020
for (let i=0; i < cluster_times.length; i++){
1909-
scroll_elem(cluster_time_marks[i], cluster_times[i], MARK_X_OFF);
2021+
scroll_elem(cluster_time_marks[i], cluster_times[i], MARK_X_OFF, bounds_start);
19102022
}
19112023
};//»
19122024
const add_cluster_time_marks=()=>{//«
@@ -2160,13 +2272,6 @@ this.onkeydown=(e,k)=>{//«
21602272
let {start, end} = get_visual_time_bounds();
21612273
seek_to_time((start+end)/2);
21622274
}
2163-
else if (k=="m_S"){
2164-
if (cluster_marks_div._dis=="none") {
2165-
cluster_marks_div._dis="";
2166-
scroll_cluster_marks();
2167-
}
2168-
else cluster_marks_div._dis="none";
2169-
}
21702275
else if (k=="s_C"){
21712276
try_save();
21722277
}
@@ -2178,18 +2283,30 @@ this.onkeydown=(e,k)=>{//«
21782283
}
21792284
else {
21802285
vid.pause();
2181-
//update_all();
2182-
// cur_set_images = new SetTimelineImages();
2183-
//draw_ruler();
21842286
vid.ontimeupdate = null;
21852287
}
21862288
}
21872289
else if (k=="m_"){
21882290
try_create_mark();
21892291
}
2292+
else if (k=="m_S"){
2293+
try_create_mark(true);
2294+
}
21902295
else if (k=="`_"){
21912296
try_seek_mark();
21922297
}
2298+
else if (k=="`_S"){
2299+
try_seek_mark(true);
2300+
}
2301+
/*
2302+
else if (k=="m_S"){
2303+
if (cluster_marks_div._dis=="none") {
2304+
cluster_marks_div._dis="";
2305+
scroll_cluster_marks();
2306+
}
2307+
else cluster_marks_div._dis="none";
2308+
}
2309+
*/
21932310
else if (k=="f_"){
21942311
fit_timeline_to_window();
21952312
}

list.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
["README.md/2181","app",["3d",["index.html/1098"]],"apps",["Audio.js/4093","BinView.js/9814","Folder.js/11196","Help.js/979","MediaPlayer.js/2074","Music.js/4844","Terminal.js/100191","TextEdit.js/5301","WorkMan.js/3808","YourApp.js/418","dev",["GetPoint.js/551","Grok.js/14796","Poker.js/36551","Three.js/5119"],"games",["Arcade.js/12599"],"hw",["MidiCtl.js/3691"],"media",["2Cameras.js/3258","Camera.js/3673","MediaPlayer.js/16115","VideoCutter.js/51055"],"template",["Basic.js/489","Template.js/396","WebAudio.js/2877"],"util",["HTML.js/1428","ImageView.js/2703","Unicoder.js/16896"]],"coms",["audio.js/1766","esprima.js/171872","extra.js/11288","fs.js/28766","games",["cfr.js/115420","poker.js/107498","slum.js/71075","zhold",["poker1.js/25062"]],"mail.js/44010","shell.js/175037","template.js/336","test",["dummy.js/21"],"test.js/2086","yt.js/66863","zhold",["mail.js/22724"]],"desk",["index.html/1184"],"index.html/486","mods",["audio",["multi_freq_worklet.js/1502","random_walk_worklet.js/3039"],"games",["GBEmulator.js/9708","NESEmulator.js/222309","binjgb.wasm/87232"],"help",["shell.js/3591"],"hw",["midi.js/2323"],"lang",["shell.js/185134"],"term",["email.js/10406","less.js/19318","log.js/13292","vim.js/162675"],"util",["libwabt.js/1299054","math.js/12125","pretty.js/93856","showdown.js/87205","walt.js/204893","wasm.js/42764","wasmparser.js/34331","webmparser.js/58730"],"workers",["poker.js/37420"]],"node",["server.js/7792","svcs",["imap.js/17772","mount.js/16553","smtp.js/1359","template.js/1831","ws.js/2156","ytdl.js/11982"]],"shell",["index.html/959"],"sys",["config.js/9365","desk.js/219010","fs.js/67626","terminal.js/4300","three.js/3443","util.js/32970"],"www",["blog.css/181","desk.css/1831","docs",["blog-template.html/291","help.html/9104","what-it-is.html/4370"],"examples",["test.sh/66"],"favicon.ico/15086","lotw256.png/41075","lotw48.png/2966","stuff",["noise.html/1669"]]]
1+
["README.md/2181","app",["3d",["index.html/1098"]],"apps",["Audio.js/4093","BinView.js/9814","Folder.js/11196","Help.js/979","MediaPlayer.js/2074","Music.js/4844","Terminal.js/100191","TextEdit.js/5301","WorkMan.js/3808","YourApp.js/418","dev",["GetPoint.js/551","Grok.js/14796","Poker.js/36551","Three.js/5119"],"games",["Arcade.js/12599"],"hw",["MidiCtl.js/3691"],"media",["2Cameras.js/3258","Camera.js/3673","MediaPlayer.js/16115","VideoCutter.js/53836"],"template",["Basic.js/489","Template.js/396","WebAudio.js/2877"],"util",["HTML.js/1428","ImageView.js/2703","Unicoder.js/16896"]],"coms",["audio.js/1766","esprima.js/171872","extra.js/11288","fs.js/28766","games",["cfr.js/115420","poker.js/107498","slum.js/71075","zhold",["poker1.js/25062"]],"mail.js/44010","shell.js/175037","template.js/336","test",["dummy.js/21"],"test.js/2086","yt.js/66863","zhold",["mail.js/22724"]],"desk",["index.html/1184"],"index.html/486","mods",["audio",["multi_freq_worklet.js/1502","random_walk_worklet.js/3039"],"games",["GBEmulator.js/9708","NESEmulator.js/222309","binjgb.wasm/87232"],"help",["shell.js/3591"],"hw",["midi.js/2323"],"lang",["shell.js/185134"],"term",["email.js/10406","less.js/19318","log.js/13292","vim.js/162675"],"util",["libwabt.js/1299054","math.js/12125","pretty.js/93856","showdown.js/87205","walt.js/204893","wasm.js/42764","wasmparser.js/34331","webmparser.js/58730"],"workers",["poker.js/37420"]],"node",["server.js/7792","svcs",["imap.js/17772","mount.js/16553","smtp.js/1359","template.js/1831","ws.js/2156","ytdl.js/11982"]],"shell",["index.html/959"],"sys",["config.js/9365","desk.js/219168","fs.js/67626","terminal.js/4300","three.js/3443","util.js/32970"],"www",["blog.css/181","desk.css/1831","docs",["blog-template.html/291","help.html/9104","what-it-is.html/4370"],"examples",["test.sh/66"],"favicon.ico/15086","lotw256.png/41075","lotw48.png/2966","stuff",["noise.html/1669"]]]

0 commit comments

Comments
 (0)