youtube-local icon indicating copy to clipboard operation
youtube-local copied to clipboard

Skip annoying Selfpromo segments not just Sponsors (Sponsorblock.js)

Open Sp0kzz opened this issue 1 year ago • 3 comments

to skip selfpromo segments too instead of just sponsors go to youtube-local/youtube/static/js open sponsorblock.js then modify the function load_sponsorblock() like this : https://pastebin.com/W4yW9Kn3

i hope the author sees this, thank you so much for this great project.

Sp0kzz avatar Apr 07 '24 22:04 Sp0kzz

i've added colors on the seekbar to distinguish the sponsor/selfpromo segments :

 	  let seekInput;
	  let gradientStops = [];
function load_sponsorblock(){
  const info_elem = Q('#skip_n');
  if (info_elem.innerText.length) return;  // already fetched
  const hash = sha256(data.video_id).substr(0,4);
  const video_obj = Q("video");
  let url = `/https://sponsor.ajay.app/api/skipSegments/${hash}?service=YouTube&categories=%5B%22sponsor%22,%22poi_highlight%22,%22selfpromo%22%5D`;
  fetch(url)
      .then(response => response.json())
      .then(r => {
    for (const video of r) {
      if (video.videoID != data.video_id) continue;
      info_elem.innerText = `(${video.segments.length} segments)`;
      const cat_n = video.segments.map(e=>e.category).sort()
          .reduce((acc,e) => (acc[e]=(acc[e]||0)+1, acc), {});
      info_elem.title = Object.entries(cat_n).map(e=>e.join(': ')).join(', ');
      for (const segment of video.segments) {
        const [start, stop] = segment.segment;
		let startPosition = ((start ) / (video_obj.duration)) * 100;
            let stopPosition = ((stop) / (video_obj.duration)) * 100;
		   		  if (segment.category === "sponsor" ){
		   gradientStops.push(`transparent ${startPosition}%, transparent ${startPosition}%, green ${startPosition}%, green ${stopPosition}%, transparent ${stopPosition}%, transparent ${stopPosition}%`);   
           }
		  else if (segment.category === "selfpromo" ){
		   gradientStops.push(`transparent ${startPosition}%, transparent ${startPosition}%, yellow ${startPosition}%, yellow ${stopPosition}%, transparent ${stopPosition}%, transparent ${stopPosition}%`);   
           }
		   		else  if (segment.category === "poi_highlight"){
				   stopPosition+=1;		
				      seekInput = document.querySelector('input[id^="plyr-seek-"]');
				     const redDiv = document.createElement('div');
    redDiv.style.position = 'absolute';
    redDiv.style.left = `${startPosition}%`;
    redDiv.style.width = `${stopPosition - startPosition}%`;
    redDiv.style.height = '50%';
	redDiv.style.top = '5px';
	redDiv.title="Highlight";
//	redDiv.style.zIndex="6666";
	//redDiv.style.pointerEvents = 'none';
    redDiv.style.backgroundColor = 'red';
	    seekInput.parentNode.appendChild(redDiv);
     const highlightSpan = document.createElement('span');
        highlightSpan.textContent = 'Highlight';
        highlightSpan.style.position = 'absolute';
        highlightSpan.style.bottom = '15px';
        highlightSpan.style.left = `${startPosition}%`;
        highlightSpan.style.transform = 'translateX(-50%)';
        highlightSpan.style.backgroundColor = 'black';
		 highlightSpan.style.zIndex="5555";
		  highlightSpan.style.fontSize="13px";
		highlightSpan.style.marginLeft="5px";
        highlightSpan.style.color = 'white';
        highlightSpan.style.padding = '2px 5px';
		  highlightSpan.style.display="none";
		seekInput.parentNode.appendChild(highlightSpan);
    seekInput.parentNode.addEventListener('mousemove', function(event) {
        const rect = redDiv.getBoundingClientRect();
        const mouseX = event.clientX - rect.left;
        const mouseY = event.clientY - rect.top;
        if (mouseX >= 0 && mouseX <= redDiv.offsetWidth && mouseY >= 0 && mouseY <= redDiv.offsetHeight) {
            highlightSpan.style.display = "block";
        } else {
            highlightSpan.style.display = "none";
        }
    });

    seekInput.parentNode.addEventListener('mouseout', function(event) {
            highlightSpan.style.display = "none";
    });
		     }
		  video_obj.addEventListener("timeupdate", function() {
          if (Q("#skip_sponsors").checked &&
              this.currentTime >= start &&
              this.currentTime < stop-1) {
            this.currentTime = stop;
          }
        });
       if (segment.category != "sponsor" && segment.category != "selfpromo") continue;	               
      }
	   const allGradientStops = gradientStops.join(', ');
	   		 seekInput = document.querySelector('input[id^="plyr-seek-"]');
	           seekInput.style.backgroundSize = `100% 50%`;
      seekInput.style.backgroundPosition = `center 5px`;
	  seekInput.style.backgroundRepeat = 'no-repeat';
  seekInput.style.backgroundImage = `linear-gradient(to right, ${allGradientStops})`;

    }
  });
}

Sp0kzz avatar Apr 07 '24 23:04 Sp0kzz

i've edited above code to have it automatically skip all segment types, color-coded on the seekbar to match YouTube ReVanced's SponsorBlock implementation. skip button support remains to be seen however.

  1. replace
let url = `/https://sponsor.ajay.app/api/skipSegments/${hash}?service=YouTube&categories=%5B%22sponsor%22,%22poi_highlight%22,%22selfpromo%22%5D`;

with

let url = `/https://sponsor.ajay.app/api/skipSegments/${hash}?service=YouTube&categories=%5B%22sponsor%22,%22poi_highlight%22,%22selfpromo%22,%22interaction%22,%22intro%22,%22outro%22,%22preview%22,%22music_offtopic%22,%22filler%22%5D`;
  1. replace
		if (segment.category === "sponsor" ){
			gradientStops.push(`transparent ${startPosition}%, transparent ${startPosition}%, green ${startPosition}%, green ${stopPosition}%, transparent ${stopPosition}%, transparent ${stopPosition}%`);   
           }
		else if (segment.category === "selfpromo" ){
			gradientStops.push(`transparent ${startPosition}%, transparent ${startPosition}%, yellow ${startPosition}%, yellow ${stopPosition}%, transparent ${stopPosition}%, transparent ${stopPosition}%`);   
           }

with

	let categoryColor = {
		"sponsor": "lime",
		"intro": "cyan",
		"outro": "violet",
		"interaction": "magenta",
		"selfpromo": "yellow",
		"music_offtopic": "orange",
		"preview": "blue",
		"filler": "purple"
	}
	if (categoryColor[segment.category]){
		   gradientStops.push(`transparent ${startPosition}%, transparent ${startPosition}%, ` + categoryColor[segment.category] + ` ${startPosition}%, ` + categoryColor[segment.category] + ` ${stopPosition}%, transparent ${stopPosition}%, transparent ${stopPosition}%`);
  1. replace
	if (segment.category != "sponsor" && segment.category != "selfpromo") continue;

with

	if (!categoryColor[segment.category]) continue;

vsr3y avatar Dec 22 '24 13:12 vsr3y

I think support for youtube-local was added to SponsorBlock itself:

https://github.com/user234683/youtube-local/issues/89#issuecomment-1421587619

Could someone check, and if not, make an issue there? We want to avoid reimplementing SponsorBlock within youtube-local and just have the extension itself do everything

user234683 avatar Feb 15 '25 20:02 user234683