@@ -22,163 +22,137 @@ async function initElements(elements) {
2222 if ( ! src || / { { \s * ( [ \w \W ] + ) \s * } } / g. test ( src ) ) continue ;
2323
2424 let initialize = initializing . get ( element ) ;
25- if ( ! initialize || initialize . src != src ) {
26- initializing . set ( element , { src } ) ;
27- if ( src ) {
28- try {
29- let response = await fetch ( src ) ;
30- if (
31- element . tagName === "AUDIO" ||
32- element . tagName === "VIDEO"
33- ) {
34- try {
35- let mediaConfig = await response . json ( ) ;
36- let sourceBuffer ;
37-
38- const mediaSource = new MediaSource ( ) ;
39- element . src = URL . createObjectURL ( mediaSource ) ;
40- mediaSource . addEventListener (
41- "sourceopen" ,
42- async ( ) => {
43- sourceBuffer = mediaSource . addSourceBuffer (
44- `${ mediaConfig [ "content-type" ] } ; codecs="${ mediaConfig . codecs } "`
45- ) ;
46-
47- sourceBuffer . addEventListener (
48- "updateend" ,
49- ( ) => {
50- console . log (
51- "Update ended, buffered ranges:" ,
52- sourceBuffer . buffered
53- ) ;
54- if (
55- ! sourceBuffer . updating &&
56- mediaSource . readyState ===
57- "open"
58- ) {
59- mediaSource . endOfStream ( ) ;
60-
61- element . addEventListener (
62- "ended" ,
63- ( ) => {
64- URL . revokeObjectURL (
65- element . src
66- ) ;
67- }
68- ) ;
69- }
70- }
71- ) ;
72- sourceBuffer . addEventListener (
73- "error" ,
74- ( e ) => {
75- console . error (
76- "SourceBuffer error event:" ,
77- e
78- ) ;
79- console . log (
80- "MediaSource readyState:" ,
81- mediaSource . readyState
82- ) ;
83- console . log (
84- "SourceBuffer updating:" ,
85- sourceBuffer . updating
86- ) ;
87- console . log (
88- "SourceBuffer buffered ranges:" ,
89- sourceBuffer . buffered
90- ) ;
91- // Any other state information you can log
92- }
93- ) ;
94-
95- getSegment (
96- sourceBuffer ,
97- mediaConfig . segments [ 0 ]
98- ) ;
99- }
100- ) ;
101-
102- mediaSource . addEventListener ( "sourceended" , ( ) => {
103- console . log ( "MediaSource ended event fired" ) ;
104- } ) ;
105-
106- mediaSource . addEventListener ( "sourceclose" , ( ) => {
107- console . log ( "MediaSource close event fired" ) ;
108- } ) ;
109-
110- // Event listener for seeking
111- element . addEventListener ( "seeking" , ( ) => {
112- let currentTime = element . currentTime ;
113- let chunkIndex = Math . floor (
114- currentTime / chunkDuration
115- ) ;
116- } ) ;
117-
118- // Event listener for seeked
119- element . addEventListener ( "seeked" , ( ) => {
120- let currentTime = element . currentTime ;
121- if ( isBuffered ( element , currentTime ) ) return ;
122-
123- let query = {
124- start : { $lte : currentTime } ,
125- end : { $gte : currentTime }
126- } ;
127-
128- let segments = queryData (
129- mediaConfig . segments ,
130- query
131- ) ;
132- for ( let segment of segments ) {
133- getSegment ( sourceBuffer , segment ) ;
134- }
135- } ) ;
136-
137- element . addEventListener ( "timeupdate" , function ( ) {
138- const bufferEnd = element . buffered . end ( 0 ) ;
139- const currentTime = element . currentTime ;
140- const threshold = 10 ; // seconds before buffer end to fetch the next segment
141-
142- if ( bufferEnd - currentTime < threshold ) {
143- // Time to fetch the next segment
144- getSegment ( sourceBuffer , mediaConfig ) ;
145- }
146- } ) ;
147- } catch ( error ) {
148- element . src = src ;
149- // let blob = await response.json();
150- // URL.createObjectURL(blob);
151- }
152- }
153- // else if (element.hasAttribute("rendered")) {
154- // element.removeAttribute("rendered");
155- // // let path = element.getAttribute("path");
156- // // if (path) {
157- // // let elements = element.querySelectorAll("[src]");
158- // // for (let i = 0; i < elements.length; i++) {
159- // // text = text.replaceAll("{{path}}", path);
160- // // }
161- // // }
162- // }
163- else {
164- element . removeAttribute ( "rendered" ) ;
165-
166- let text = await response . text ( ) ;
167- if ( text ) {
168- let path = element . getAttribute ( "path" ) ;
169- if ( path ) text = text . replaceAll ( "{{path}}" , path ) ;
170- element . setValue ( text ) ;
171- initializing . delete ( element ) ;
172- }
25+ if ( initialize && initialize . src === src ) continue ;
26+
27+ initializing . set ( element , { src } ) ;
28+ try {
29+ let state = localStorage . getItem ( "state" ) ; // Assume this is your state object
30+ let response = await fetch ( src , {
31+ headers : {
32+ "X-State" : state // Custom header to send state
33+ }
34+ } ) ;
35+
36+ if ( element . tagName === "AUDIO" || element . tagName === "VIDEO" ) {
37+ initMediaSource ( element , src ) ;
38+ } else {
39+ element . removeAttribute ( "rendered" ) ;
40+
41+ let text = await response . text ( ) ;
42+ if ( text ) {
43+ let pathElement = element . closest ( "[path]" ) ;
44+ if ( pathElement ) {
45+ let path =
46+ pathElement . getAttribute ( "path" ) || getPath ( ) ;
47+ if ( path ) text = text . replaceAll ( "$relativePath" , path ) ;
17348 }
174- } catch ( err ) {
175- console . log ( "FetchSrc error:" + err ) ;
49+ element . setValue ( text ) ;
50+ initializing . delete ( element ) ;
17651 }
17752 }
53+ } catch ( err ) {
54+ console . log ( "FetchSrc error:" + err ) ;
17855 }
17956 }
18057}
18158
59+ function getPath ( ) {
60+ let currentPath = window . location . pathname . replace ( / \/ [ ^ \/ ] * $ / , "" ) ; // Remove file from path
61+ let depth = currentPath . split ( "/" ) . filter ( Boolean ) . length ; // Count depth levels
62+
63+ return depth > 0 ? "../" . repeat ( depth ) : "./" ; // Return the correct relative path
64+ }
65+
66+ async function initMediaSource ( element , src ) {
67+ try {
68+ let mediaConfig = await response . json ( ) ;
69+ let sourceBuffer ;
70+
71+ const mediaSource = new MediaSource ( ) ;
72+ element . src = URL . createObjectURL ( mediaSource ) ;
73+ mediaSource . addEventListener ( "sourceopen" , async ( ) => {
74+ sourceBuffer = mediaSource . addSourceBuffer (
75+ `${ mediaConfig [ "content-type" ] } ; codecs="${ mediaConfig . codecs } "`
76+ ) ;
77+
78+ sourceBuffer . addEventListener ( "updateend" , ( ) => {
79+ console . log (
80+ "Update ended, buffered ranges:" ,
81+ sourceBuffer . buffered
82+ ) ;
83+ if (
84+ ! sourceBuffer . updating &&
85+ mediaSource . readyState === "open"
86+ ) {
87+ mediaSource . endOfStream ( ) ;
88+
89+ element . addEventListener ( "ended" , ( ) => {
90+ URL . revokeObjectURL ( element . src ) ;
91+ } ) ;
92+ }
93+ } ) ;
94+
95+ sourceBuffer . addEventListener ( "error" , ( e ) => {
96+ console . error ( "SourceBuffer error event:" , e ) ;
97+ console . log ( "MediaSource readyState:" , mediaSource . readyState ) ;
98+ console . log ( "SourceBuffer updating:" , sourceBuffer . updating ) ;
99+ console . log (
100+ "SourceBuffer buffered ranges:" ,
101+ sourceBuffer . buffered
102+ ) ;
103+ // Any other state information you can log
104+ } ) ;
105+
106+ getSegment ( sourceBuffer , mediaConfig . segments [ 0 ] ) ;
107+ } ) ;
108+
109+ mediaSource . addEventListener ( "sourceended" , ( ) => {
110+ console . log ( "MediaSource ended event fired" ) ;
111+ } ) ;
112+
113+ mediaSource . addEventListener ( "sourceclose" , ( ) => {
114+ console . log ( "MediaSource close event fired" ) ;
115+ } ) ;
116+
117+ // Event listener for seeking
118+ element . addEventListener ( "seeking" , ( ) => {
119+ let currentTime = element . currentTime ;
120+ let chunkIndex = Math . floor ( currentTime / chunkDuration ) ;
121+ } ) ;
122+
123+ // Event listener for seeked
124+ element . addEventListener ( "seeked" , ( ) => {
125+ let currentTime = element . currentTime ;
126+ if ( isBuffered ( element , currentTime ) ) return ;
127+
128+ let query = {
129+ start : { $lte : currentTime } ,
130+ end : { $gte : currentTime }
131+ } ;
132+
133+ let segments = queryData ( mediaConfig . segments , query ) ;
134+ for ( let segment of segments ) {
135+ getSegment ( sourceBuffer , segment ) ;
136+ }
137+ } ) ;
138+
139+ element . addEventListener ( "timeupdate" , function ( ) {
140+ const bufferEnd = element . buffered . end ( 0 ) ;
141+ const currentTime = element . currentTime ;
142+ const threshold = 10 ; // seconds before buffer end to fetch the next segment
143+
144+ if ( bufferEnd - currentTime < threshold ) {
145+ // Time to fetch the next segment
146+ getSegment ( sourceBuffer , mediaConfig ) ;
147+ }
148+ } ) ;
149+ } catch ( error ) {
150+ element . src = src ;
151+ // let blob = await response.json();
152+ // URL.createObjectURL(blob);
153+ }
154+ }
155+
182156async function getSegment ( sourceBuffer , segment ) {
183157 // TODO: use socket/crud/file with room using the url to get one or more segments and append
184158 let segments = [ ] ;
@@ -273,6 +247,19 @@ observer.init({
273247 }
274248} ) ;
275249
250+ observer . init ( {
251+ name : "CoCreateSrcOperator" ,
252+ observe : [ "addedNodes" ] ,
253+ selector : "img" ,
254+ // selector: "img, video, audio, script, input, iframe, frame, link, source",
255+ callback : function ( mutation ) {
256+ let src = mutation . target . getAttribute ( "src" ) ;
257+ if ( src ) {
258+ mutation . target . setAttribute ( "src" , src ) ;
259+ }
260+ }
261+ } ) ;
262+
276263observer . init ( {
277264 name : "CoCreateSrcAttributes" ,
278265 observe : [ "attributes" ] ,
0 commit comments