๊ด๊ณ ๊ฐ ๋จ๋ <video>
element๋ฅผ ์ก์ currentTime=1000
๊ฐ์ ์ค๋ค
์ง๋ ๋ฒ์ ๋ง๋ chrome extension์ ์ ๋์ํ์ผ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๊ทธ์ ๊ด๊ณ ๋ฅผ ์์ฒญํ ์ ๋ฐ์ ์์๋ค
๊ทธ๋ฆฌ๊ณ setInterval()
์ ํตํด 1์ด๋ง๋ค pollingํ๋ ๋ฐฉ์์ ๊ตฌํํ๊ธฐ์๋ ํธํ๋ ์ข ๊ตฌ๋ฆฐ ๋๋์ด ๋ค์๋ค. ์์ง ์ข ๋ ์ ํ ์ ์๋ค...
developer tool ์ ํตํด youtube ์์ค์ฝ๋๋ฅผ ๋๋ฒ๊น
ํ๋ฉฐ skip()
๊ฐ์ ๊ฐ๊ฟ๐ ํจ์๊ฐ ์๋์ง ํ์
base.js ๋ฅผ prettifyํ ๊ฒฝ์ฐ 9๋ง์ค์ ๋ฌํ๋๋ฐ, ์์ฌ๊ฐ๋ ๋ถ๋ถ์ ํ์คํ์ค ๋ฐ๋ผ๊ฐ๋ฉฐ ๋ถ์ํด๋ณด์๋ค.
uglify๊ฐ ๋๋ฌด ์๋ผ์๊ณ ์ผ๋ฐ์ ์ธ ์น์ฑ๊ณผ ๋ฌ๋ฆฌ ์ฝ์คํ์ด ์ ์๋์์ ๋๋ฒ๊น
์ด ์ฝ์ง ์์๋ค. ์ถ๊ฐ์ ์ผ๋ก youtube-dl github์ ๊ณต๊ฐ๋ youtube์ชฝ ์์ค์ฝ๋๋ ๊ฐ์ด ๋ดค์ผ๋ ํฐ ๋์์ ๋์ง ์์๋ค. ์ฌํด๋ฅผ ํ์ฌํ๋ ๊ธฐ๋ถ์ด์๊ณ ๋ช ์๊ฐ์ฏค ๋ณด๋ค๋ณด๋ ์ ์ ๋๊ฐ๊ฑฐ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์ด, ๊ทธ๋ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์๋ณด๊ธฐ๋ก ํ๋ค
github์ public ๊ณต๊ฐ๋ chrome extension๋ค๋ ๋ง์ฐฌ๊ฐ์ง๋ก skip ๋ฒํผ์ triggerํ๋ ๋ถ์์ ํ ๋ฐฉ์์ด๋ผ skip ๋ฒํผ์ด ์๋ ๊ด๊ณ ์ ๊ฒฝ์ฐ ์์๋ฌด์ฑ ์ด์๋ค. ๊ทธ๋ฐ๋ฐ AdBlock extension์ ๋ชจ๋ ์ข ๋ฅ์ YouTube ๊ด๊ณ ๋ฅผ skipํ๋ค. ์ข ๋ ์ข์ ๋ฐฉ๋ฒ์ ์ฐ๋ ๋ชจ์์ธ๋ฐ ์ํ๊น๊ฒ๋ ์คํ์์ค๊ฐ ์๋์๋ค. ์์ฌ์ด๋๋ก adblock์ ์์ค์ฝ๋๋ฅผ ๊น๋ณด๊ณ ์ https://robwu.nl/crxviewer ๋ฅผ ์ด์ฉํ์ฌ extension ํ์ผ์ ์ป์์ ์์๋ค. ๋คํํ uglify๊ฐ ์๋ผ์๊ณ ์น์ ํ๊ฒ ์ฃผ์๋ ๋ฌ๋ ค์๋ค ๊ฐธ๊ฟ~๐
500์ค ์ ๋์ ์งง์ content script์๊ณ , ์ฃผ๋ก ๋ ๊ฐ์ง ๊ฒฝ์ฐ์ ๋ํด ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌํ๋ค
1. skip ad ๋ฒํผ์ด ์๋ ๊ด๊ณ -> hidden์ฒ๋ฆฌ๋ ๋ฒํผ์ ํด๋ฆญ
2. skip ad ๋ฒํผ์ด ์๋ ๊ด๊ณ -> <video>
ํ๊ทธ๋ฅผ ์ก์ currentTime = 10000
์ฒ๋ฆฌ
์ฒซ๋ฒ์งธ ๊ฒฝ์ฐ๋ ์ด๋ฏธ ์๊ณ ์๊ณ , ๊ถ๊ธํ๋ ๋๋ฒ์งธ ๊ฒฝ์ฐ๋ ํ์์์ด ๋์ฌ ์ ๋๋ก ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๊ณ ์๋ค. "์ด๊ฒ ๋๋ค๊ณ ?" ๋ผ๋ ์๊ฐ์ด ๋ฐ๋ก ๋ค์์ผ๋ ์ ํญ์ ์ด์ด ์คํํด๋ณธ ๊ฒฐ๊ณผ ์ ๋์ํ์๋ค. ์ค๋ง๊ฐ์ง ์๊ฐ์ด ์ค์ณ๊ฐ์ผ๋ ๋ค์ ์ ๊ธฐ๋ก ํ๊ณ ์ผ๋จ ๋ด chrome extension์ ์ ์ฉ๋ถํฐ ํด๋ณด๊ธฐ๋ก ํ๋ค.
์์ ์ฌ์์ ์ฌ์ฉ๋๋ <video>
Element๋ HTMLMediaElement
์ ๊ตฌํ์ฒด๋ก์ currentTime
์์ฑ์ ๊ฐ์ง๊ณ ์๋ค. ์ด ๊ฐ์ ํ์ฌ ๋ณด๊ณ ์๋ ์์์ ๋ณด๊ณ ์๋ ์์์ ํ์ฌ ์๊ฐ์ ์ด๋จ์๋ก ํํํ๋๋ฐ, ์ด ๊ฐ์ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ๋ณ๊ฒฝ๋ ์๊ฐ์ผ๋ก ์ด๋(seek)ํ๊ฒ ๋๋ค. ์ด ์์ฑ์ ์ด์ฉํ์ฌ ๊ด๊ณ ๊ฐ ๋ฐ ๊ฒฝ์ฐ 1000์ด ๋ค๋ก ์ด๋์์ผ๋ฒ๋ฆฌ๋ฉด ๊ด๊ณ ๊ฐ ๋๋๊ฒ ๋๋ค. ๋น๊ฒํ ์๋ฒ์ด์ง๋ง ๊ณ ๋ง๊ฒ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ์ด ๋งค์ฐ ๊ฐ๋จํ๋ค๋ ์ฅ์ ์ด ์๋ค.
const timeWarp = () => {
const video = document.querySelector("html5-video-player video");
video.currenTime = 10000;
}
ํ๊ต๋ ํ์ฌ์์ ์๋ฌด์๊ฐํด์ผํ๋ ๊ต์ก ๋์์๋ ์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ์ skip์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ๊ธฐ์กด ์ฝ๋์ ์์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ๊ด๊ณ ๊ฐ 2์ฐํ๋ก ๋จ๋๋ผ๋ ๊ด๊ณ ๋ฅผ ์ ๋๊ธธ์ ์๋ค.
ํ์ง๋ง ์ ๋ณด๋ฉด ๊ด๊ณ ๊ฐ ์ฐ์์ผ๋ก ๋จ๋ ๊ฒฝ์ฐ์๋ 1์ด์ ๋ ๊ด๊ณ ๋ฅผ ๋ณด๊ฒ๋๋ค. setInterval์ 1์ด๋ง๋ค ๊ฑธ์ด๋์ ํ์ธ๋ฐ, ๊ทธ๋ ๋ค๊ณ interval๊ฐ์ 1์ด๋ณด๋ค ์ค์ด๋ฉด ๋ธ๋ผ์ฐ์ ์ ๋ถํ๊ฐ ๋์ด๋๊ฒ ๋๋ค. ์์ polling ๋ฐฉ์์ ๋ฒ๋ฆฌ๊ณ ์ข๋ ๊ณ ๊ธ์ค๋ฌ์ด ๋ฐฉ๋ฒ์ ์จ๋ณด๊ธฐ๋ก ํ๋ค.
์ง๋๋ฒ ํฌ์คํธ์์ mutationObserver
๋ฅผ ์ ๊น ์ธ๊ธํ์๋๋ฐ, DOM์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๋ API์ด๋ค. ๊ด๊ณ ๊ฐ ๋ ์์ ๋๋ DOM ์ด๋๊ฐ ํ์๊ฐ ๋ ๊ฒ์ด๊ณ ์ด๋ฅผ ๊ฐ์งํ์ฌ ๊ด๊ณ ๋ฅผ skipํ๋๋ก ํ๋ฉด ๋ธ๋ผ์ฐ์ ์ ๋ถํ๋ฅผ ์ ๊ฒ ์ค์ ์์๊ฒ์ด๋ค.
<video>
๋ฅผ ๊ฐ์ธ๊ณ ์๋ div.html5-video-player
๋ฅผ ๋ณด๋ ๊ด๊ณ ๊ฐ ๋ ์์ ๋ "ad-showing"์ด๋ผ๋ class๊ฐ ์กด์ฌํ์ฌ ์ด๋ฅผ ๊ฐ์งํ์ฌ ๊ด๊ณ ๋ฅผ skipํ๋๋ก ๊ตฌํํด๋ณธ๋ค. trigger()
๋ ์ง๋ ํฌ์คํ
์์ ๊ตฌํํ ๊ฐ์ ๋ฒํผ ํด๋ฆญ ํจ์, timeWarp()
๋ ์ด๋ฒ์ ๊ตฌํํ ํจ์.
const checkAdsPlaying = (mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.target.classList.contains("ad-showing")) {
const videoWrapper = mutation.target;
trigger(videoWrapper) || timeWarp(videoWrapper)
}
}
};
const observer = new MutationObserver(checkAdsPlaying);
observer.observe(target, { attributes: true, attributeFilter: ["class"] });
๋ฌผ๋ก ์ด๊ฒ ๋ง์ผ๋ก ์ ๋์ํ์ง๋ ์๋๋ฐ
<video>
element๊ฐ DOM์ ๋ถ์ ์ดํ์ ์์ ์ฝ๋๊ฐ ์คํ๋์ด์ผ ํจtimeWarp
๊ฐ 7ํ์ ๋ ํธ์ถcurrentTime
๊ฐ์ ๋ฐ๊พธ๊ณ ๋์ '์ฆ์' ๊ด๊ณ ๊ฐ ๋์ด๊ฐ์ง๋ ์๋๊ฒ ๊ฐ์์์ ์ด์๋ฅผ ๋์ถฉ ํด๊ฒฐํ๊ณ ์ต์ข
๊ตฌํ๋ ์ ์ฒด ์ฝ๋๋ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐ ๋ฐ๋๋ค.
interval ์์ด ๊ด๊ณ ๊ฐ ๋จ๋ฉด ๋ฐ๋ก skip ํ๋ฏ๋ก, ๊ด๊ณ ๊ฐ 2์ฐํ๋ก ๋ฑ์ฅํ๋ ๊ฒฝ์ฐ์๋ ์ข๋ ์ค๋ฌด์ค~ํ๊ฒ ๊ด๊ณ skip์ด ๋๋ค!
์ด์ ์ฌ๋งํ ๊ฒฝ์ฐ์ ๋ํด์๋ ๊ด๊ณ ์ฐจ๋จ์ด ์ ๋๋ค. ๋ง์ง๋ง ์ผ์ด์ค๋ "youtube.com" ๋ฟ๋ง ์๋๋ผ ๋ชจ๋ ๋ฐฉ๋ฌธํ๋ ์ฌ์ดํธ์ ๋ํด chrome-extension์ ์คํํ ์ ์๋๋ก ๊ถํ์ค์ ์ ํด์ผ ํ๋๋ฐ ๊ทธ๊ฒ๊น์ง๋ ๋ฐ๋ผ์ง ์์ผ๋ฏ๋ก ํ์ง ์๊ธฐ๋ก ํจ.
ํฌ๋กฌ ์ํฌ๋ฆฟ๋ชจ๋๋ก ์ ํญ์ ์ด๊ณ , ์ ํฌ๋ธ๋ฅผ ์ผ์ melon top 100์ด๋ ๋ฉ๊ณ ํ๋ฆฌ์คํ์ผ๊ณผ ๊ฐ์ด ์ ์๊ถ์ด ๊ฑธ๋ ค์๋ ์์์ ์์ฒญํ๋ฉด ๋์ ํ๋ฅ ๋ก ๊ด๊ณ ๊ฐ ๋ฌ๋ค