Skip to content

Commit

Permalink
Improve video detection speed
Browse files Browse the repository at this point in the history
  • Loading branch information
raxod502 committed Nov 11, 2022
1 parent eba8608 commit f3b1230
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 33 deletions.
5 changes: 5 additions & 0 deletions extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ multiple positions when seeking, especially with a large number of
clients connected. This has been made much less likely by implementing
a slightly modified synchronization algorithm.

Detection of the active video element is faster now in most cases. If
there is only one choice, then it is selected immediately. Only if
there is more than one candidate and Hypercast cannot disambiguate do
you have to hit play on the main content to show it which is which.

## 0.0.7

End-to-end encryption is now used, so the server has no knowledge of
Expand Down
81 changes: 48 additions & 33 deletions extension/content-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,58 @@ const getCandidateVideos = () => {
};

const detectPrimaryVideo = () => {
let looping = true;
let guessedPrimaryVideo = null;
// Create a promise that will resolve when we have found at least
// one candidate video. However, we keep updating our best guess
// even after this promise resolves, until the caller of
// detectPrimaryVideo invokes the returned function, at which point
// we return the current best guess and abort further calculations
// (and, we block until at least one guess is found, if none has
// been found yet).
const foundOne = new Promise(async (resolve) => {
log(`Video detection: searching for active videos`);
const lastTimes = new Map();
while (looping) {
const activeVideos = new Set();
for (const video of getCandidateVideos()) {
if (
lastTimes.has(video) &&
lastTimes.get(video) !== video.currentTime
) {
activeVideos.add(video);
}
lastTimes.set(video, video.currentTime);
}
let foundOne = null;
let looping = true;
const candidateVideos = getCandidateVideos();
log(`Video detection: found ${candidateVideos.length} candidate video(s)`);
if (candidateVideos.length === 1) {
log(
`Video detection: since exactly 1 candidate video, assuming it is correct`
);
guessedPrimaryVideo = candidateVideos[0];
foundOne = Promise.resolve();
} else {
// Create a promise that will resolve when we have found at least
// one candidate video. However, we keep updating our best guess
// even after this promise resolves, until the caller of
// detectPrimaryVideo invokes the returned function, at which point
// we return the current best guess and abort further calculations
// (and, we block until at least one guess is found, if none has
// been found yet).
foundOne = new Promise(async (resolve) => {
log(
`Video detection: found ${
activeVideos.size
} active videos ${JSON.stringify(
[...activeVideos].map((video) => video.id || "(anonymous <video>)")
)}`
`Video detection: unable to disambiguate, checking for currently playing videos every 200ms`
);
if (activeVideos.size > 0) {
guessedPrimaryVideo = [...activeVideos.values()][0];
resolve();
const lastTimes = new Map();
while (looping) {
const activeVideos = new Set();
for (const video of getCandidateVideos()) {
if (
lastTimes.has(video) &&
lastTimes.get(video) !== video.currentTime
) {
activeVideos.add(video);
}
lastTimes.set(video, video.currentTime);
}
if (activeVideos.size > 0) {
log(
`Video detection: found ${
activeVideos.size
} active videos ${JSON.stringify(
[...activeVideos].map(
(video) => video.id || "(anonymous <video>)"
)
)}`
);
guessedPrimaryVideo = [...activeVideos.values()][0];
resolve();
}
await new Promise((resolve) => setTimeout(resolve, 200));
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
});
});
}
return {
get: () =>
foundOne.then(() => {
Expand Down

0 comments on commit f3b1230

Please sign in to comment.