Compare commits

..

14 Commits
v0.3 ... v1.0.2

Author SHA1 Message Date
Ajay Ramachandran
c7da0f0c65 Merge pull request #5 from ajayyy/experimental
Added option to disable view count tracking
2019-07-23 21:09:36 -04:00
Ajay Ramachandran
0f561d4a5a Added option to disable the view count tracking. 2019-07-23 21:06:36 -04:00
Ajay Ramachandran
55c7529731 Update README.md 2019-07-23 20:06:08 -04:00
Ajay Ramachandran
30c6437160 Merge pull request #4 from ajayyy/experimental
View count additions and fixes
2019-07-23 20:01:23 -04:00
Ajay Ramachandran
e8ff6171eb Updated version number 2019-07-23 19:58:30 -04:00
Ajay Ramachandran
b7764fc634 Added feature to prevent tons of sponsors reported next to each other from annoying the user. 2019-07-23 19:37:33 -04:00
Ajay Ramachandran
9913e99a6a Fixed curly bracket that for some reason was in the wrong place. 2019-07-23 19:33:12 -04:00
Ajay Ramachandran
c91c08a17f Made it send a request to the server to sponsor skip views. 2019-07-23 18:42:44 -04:00
Ajay Ramachandran
86bffeb96c Made it display how many views your submissions have received. 2019-07-23 18:32:05 -04:00
Ajay Ramachandran
c580a7dc7c Updated icons to be square and fixed titling 2019-07-23 17:44:29 -04:00
Ajay Ramachandran
22df50e3fe Made a separate manifest file for Firefox 2019-07-22 21:21:00 -04:00
Ajay Ramachandran
6d32b88490 Updated gitignore for file rename 2019-07-22 21:13:33 -04:00
Ajay Ramachandran
95dee05e92 Merge branch 'experimental' of https://github.com/ajayyy/SponsorBlock into experimental 2019-07-22 21:12:01 -04:00
Ajay Ramachandran
21220bf2d3 Added support for Firefox. 2019-07-22 21:11:37 -04:00
12 changed files with 271 additions and 43 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,2 @@
content-config.js
config.js
ignored

View File

@@ -5,6 +5,12 @@
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
# Available for Chrome and Firefox
Chrome: https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone/
Firefox: https://addons.mozilla.org/addon/sponsorblock/
# Server
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
@@ -19,13 +25,9 @@ Hopefully this project can be combined with projects like [this](https://github.
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip). That extension has the basic video skipping functionality.
# Chrome extension
# Build Yourself
It will be on the chrome webstore soon once I get some more UI features in, such as an icon. For now, you can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
# Firefox extension
None at the moment
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
# Credit

View File

@@ -1,3 +0,0 @@
//this file is loaded along iwth content.js
//this file sets the server to connect to, and is gitignored
var serverAddress = "http://localhost";

View File

@@ -1,4 +1,4 @@
.playerButton {
.playerButtonImage {
height: 60%;
top: 0;
bottom: 0;
@@ -6,6 +6,10 @@
margin: auto;
}
.playerButton {
vertical-align: top;
}
.sponsorSkipObject {
font-family: 'Source Sans Pro', sans-serif;
}

View File

@@ -21,6 +21,9 @@ var v;
//the last time looked at (used to see if this time is in the interval)
var lastTime;
//the last time skipped to
var lastTimeSkippedTo = -1;
//the last time in the video a sponsor was skipped
//used for the go back button
var lastSponsorTimeSkipped = null;
@@ -33,6 +36,17 @@ var showingStartSponsor = true;
//should the video controls buttons be added
var hideVideoPlayerControls = false;
//should view counts be tracked
var trackViewCount = false;
chrome.storage.sync.get(["trackViewCount"], function(result) {
let trackViewCountStorage = result.trackViewCount;
if (trackViewCountStorage != undefined) {
trackViewCount = trackViewCountStorage;
} else {
trackViewCount = true;
}
});
//if the notice should not be shown
//happens when the user click's the "Don't show notice again" button
var dontShowNotice = false;
@@ -83,6 +97,10 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
updateVisibilityOfPlayerControlsButton();
}
if (request.message == "trackViewCount") {
trackViewCount = request.value;
}
});
function videoIDChange(id) {
@@ -117,7 +135,6 @@ function videoIDChange(id) {
function sponsorsLookup(id) {
v = document.querySelector('video') // Youtube video player
let xmlhttp = new XMLHttpRequest();
//check database for sponsor times
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
@@ -151,28 +168,36 @@ function sponsorsLookup(id) {
}
function sponsorCheck(sponsorTimes) { // Video skipping
//see if any sponsor start time was just passed
for (let i = 0; i < sponsorTimes.length; i++) {
//the sponsor time is in between these times, skip it
//if the time difference is more than 1 second, than the there was probably a skip in time,
// and it's not due to playback
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime) {
//skip it
v.currentTime = sponsorTimes[i][1];
//see if any sponsor start time was just passed
for (let i = 0; i < sponsorTimes.length; i++) {
//the sponsor time is in between these times, skip it
//if the time difference is more than 1 second, than the there was probably a skip in time,
// and it's not due to playback
//also check if the last time skipped to is not too close to now, to make sure not to get too many
// sponsor times in a row (from one troll)
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime &&
(lastTimeSkippedTo == -1 || Math.abs(v.currentTime - lastTimeSkippedTo) > 1)) {
//skip it
v.currentTime = sponsorTimes[i][1];
lastTimeSkippedTo = sponsorTimes[i][1];
lastSponsorTimeSkipped = sponsorTimes[i][0];
let currentUUID = UUIDs[i];
lastSponsorTimeSkippedUUID = currentUUID;
lastSponsorTimeSkipped = sponsorTimes[i][0];
let currentUUID = UUIDs[i];
lastSponsorTimeSkippedUUID = currentUUID;
//send out the message saying that a sponsor message was skipped
openSkipNotice();
//send out the message saying that a sponsor message was skipped
openSkipNotice();
setTimeout(() => closeSkipNotice(currentUUID), 7000);
}
setTimeout(() => closeSkipNotice(currentUUID), 7000);
lastTime = v.currentTime;
//send telemetry that a this sponsor was skipped happened
if (trackViewCount) {
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
}
}
}
lastTime = v.currentTime;
}
function goBackToPreviousTime(UUID) {
@@ -193,13 +218,13 @@ function addPlayerControlsButton() {
let startSponsorButton = document.createElement("button");
startSponsorButton.id = "startSponsorButton";
startSponsorButton.className = "ytp-button";
startSponsorButton.className = "ytp-button playerButton";
startSponsorButton.setAttribute("title", "Sponsor Starts Now");
startSponsorButton.addEventListener("click", startSponsorClicked);
let startSponsorImage = document.createElement("img");
startSponsorImage.id = "startSponsorImage";
startSponsorImage.className = "playerButton";
startSponsorImage.className = "playerButtonImage";
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
//add the image to the button
@@ -269,7 +294,7 @@ function addSubmitButton() {
//make a submit button
let submitButton = document.createElement("button");
submitButton.id = "submitButton";
submitButton.className = "ytp-button";
submitButton.className = "ytp-button playerButton";
submitButton.setAttribute("title", "Submit Sponsor Times");
submitButton.addEventListener("click", submitSponsorTimes);
//hide it at the start
@@ -277,7 +302,7 @@ function addSubmitButton() {
let submitImage = document.createElement("img");
submitImage.id = "submitButtonImage";
submitImage.className = "playerButton";
submitImage.className = "playerButtonImage";
submitImage.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
//add the image to the button

61
firefox_manifest.json Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "SponsorBlock - YouTube Sponsorship Blocker",
"short_name": "SponsorBlock",
"version": "1.0.2",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"content_scripts": [
{
"matches": [
"https://*.youtube.com/*"
],
"js": [
"config.js",
"content.js"
],
"css": [
"content.css",
"./libs/Source+Sans+Pro.css"
]
}
],
"web_accessible_resources": [
"icons/LogoSponsorBlocker256px.png",
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
"icons/PlayerUploadIconSponsorBlocker256px.png",
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png"
],
"permissions": [
"tabs",
"storage",
"notifications",
"https://sponsor.ajay.app/*"
],
"browser_action": {
"default_title": "SponsorBlock",
"default_popup": "popup.html"
},
"background": {
"scripts":[
"config.js",
"background.js"
]
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png",
"256": "icons/LogoSponsorBlocker256px.png"
},
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlocker@ajay.app",
"strict_min_version": "57.0"
}
},
"manifest_version": 2
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -1,7 +1,8 @@
{
"name": "YTSponsorSkip",
"version": "1.0",
"description": "Skip youtube video sponsors.",
"name": "SponsorBlock - YouTube Sponsorship Blocker",
"short_name": "SponsorBlock",
"version": "1.0.2",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"content_scripts": [
{
"matches": [
@@ -30,7 +31,8 @@
"permissions": [
"tabs",
"storage",
"notifications"
"notifications",
"https://sponsor.ajay.app/*"
],
"browser_action": {
"default_title": "SponsorBlock",

View File

@@ -41,8 +41,26 @@
<h2 class="recordingSubtitle">Record the times of a sponsorship</h2>
<p id="sponsorTimesContributionsDisplay" style="display: none">
So far, you've submitted no sponsor times.
<p>
<span id=sponsorTimesContributionsContainer style="display: none">
So far, you've submitted
<span id="sponsorTimesContributionsDisplay">
0
</span>
<span id="sponsorTimesContributionsDisplayEndWord">
sponsors.
</span>
</span>
<span id=sponsorTimesViewsContainer style="display: none">
You have saved people from
<span id="sponsorTimesViewsDisplay">
0
</span>
<span id="sponsorTimesViewsDisplayEndWord">
sponsor segments.
</span>
</span>
</p>
<p>
@@ -94,14 +112,37 @@
<button id="hideVideoPlayerControls" class="warningButton">Hide Button On YouTube Player</button>
<button id="showVideoPlayerControls" style="display: none" class="warningButton">Show Button On YouTube Player</button>
<br/>
<sub>
This hides the button that appears on the YouTube player to submit sponsors. I can see this being annoying for some
people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears,
use the button that appears on the notice saying "Don't show this again". You can always enable these settings again
later.
</sub>
<br/>
<br/>
<button id="disableSponsorViewTracking" class="warningButton">Disable Sponsor View Tracking</button>
<button id="enableSponsorViewTracking" style="display: none" class="warningButton">Enable Sponsor View Tracking</button>
<br/>
<sub>
This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and
used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message
to the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers
are accurate. :)
</sub>
<br/>
<br/>
<button id="showNoticeAgain" style="display: none" class="dangerButton">Show Notice Again</button>
</div>
</div>
</div>
</center>
<!-- Scripts that need to load after the html -->
<script src="config.js"></script>
<script src="popup.js"></script>
</html>

102
popup.js
View File

@@ -5,6 +5,8 @@ document.getElementById("submitTimes").addEventListener("click", submitTimes);
document.getElementById("showNoticeAgain").addEventListener("click", showNoticeAgain);
document.getElementById("hideVideoPlayerControls").addEventListener("click", hideVideoPlayerControls);
document.getElementById("showVideoPlayerControls").addEventListener("click", showVideoPlayerControls);
document.getElementById("disableSponsorViewTracking").addEventListener("click", disableSponsorViewTracking);
document.getElementById("enableSponsorViewTracking").addEventListener("click", enableSponsorViewTracking);
document.getElementById("optionsButton").addEventListener("click", openOptions);
document.getElementById("reportAnIssue").addEventListener("click", reportAnIssue);
@@ -38,20 +40,61 @@ chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
}
});
//show proper tracking option
chrome.storage.sync.get(["trackViewCount"], function(result) {
let trackViewCount = result.trackViewCount;
if (trackViewCount != undefined && !trackViewCount) {
document.getElementById("disableSponsorViewTracking").style.display = "none";
document.getElementById("enableSponsorViewTracking").style.display = "unset";
}
});
//get the amount of times this user has contributed and display it to thank them
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
if (result.sponsorTimesContributed != undefined) {
let sponsorTimesContributionsContainer = document.getElementById("sponsorTimesContributionsContainer");
let sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
let sponsorTimesContributionsDisplayEndWord = document.getElementById("sponsorTimesContributionsDisplayEndWord");
if (result.sponsorTimesContributed > 1) {
sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor times.";
sponsorTimesContributionsDisplayEndWord.innerText = "sponsors."
} else {
sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor time.";
sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
}
sponsorTimesContributionsDisplay.style.display = "unset";
sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
sponsorTimesContributionsContainer.style.display = "unset";
//get the userID
chrome.storage.sync.get(["userID"], function(result) {
let userID = result.userID;
if (userID != undefined) {
//there are probably some views on these submissions then
//get the amount of views from the sponsors submitted
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
if (viewCount != 0) {
let sponsorTimesViewsContainer = document.getElementById("sponsorTimesViewsContainer");
let sponsorTimesViewsDisplay = document.getElementById("sponsorTimesViewsDisplay");
let sponsorTimesViewsDisplayEndWord = document.getElementById("sponsorTimesViewsDisplayEndWord");
if (viewCount > 1) {
sponsorTimesViewsDisplayEndWord.innerText = "sponsor segments."
} else {
sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
}
sponsorTimesViewsDisplay.innerText = viewCount;
sponsorTimesViewsContainer.style.display = "unset";
}
}
});
}
});
}
});
chrome.tabs.query({
active: true,
currentWindow: true
@@ -366,6 +409,40 @@ function showVideoPlayerControls() {
document.getElementById("showVideoPlayerControls").style.display = "none";
}
function disableSponsorViewTracking() {
chrome.storage.sync.set({"trackViewCount": false});
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "trackViewCount",
value: false
});
});
document.getElementById("disableSponsorViewTracking").style.display = "none";
document.getElementById("enableSponsorViewTracking").style.display = "unset";
}
function enableSponsorViewTracking() {
chrome.storage.sync.set({"trackViewCount": true});
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "trackViewCount",
value: true
});
});
document.getElementById("enableSponsorViewTracking").style.display = "none";
document.getElementById("disableSponsorViewTracking").style.display = "unset";
}
function updateStartTimeChosen() {
//update startTimeChosen variable
if (!startTimeChosen) {
@@ -466,6 +543,25 @@ function getFormattedTime(seconds) {
return formatted;
}
function sendRequestToServer(type, address, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(type, serverAddress + address, true);
if (callback != undefined) {
xmlhttp.onreadystatechange = function () {
callback(xmlhttp, false);
};
xmlhttp.onerror = function(ev) {
callback(xmlhttp, true);
};
}
//submit this request
xmlhttp.send();
}
function getYouTubeVideoID(url) { // Return video id or false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);