Tarik untuk refresh

Memuat...

0; var canB2 = !!(d.stream_urls && d.stream_urls.length); var canGd = hasGd; var canHls = !!d.hls_url; this._prevServer = this.server; // Fullscreen bisa native (document.fullscreenElement) ATAU // mode fallback CSS Plyr (`.plyr--fullscreen-fallback`, dipakai // WebView / browser tanpa Fullscreen API). Kalau hanya cek // document.fullscreenElement, di mode fallback ini nilainya // null -> re-enter tak pernah jalan -> keluar fullscreen. this._wasFullscreen = !!(document.fullscreenElement || document.querySelector('.plyr--fullscreen-fallback')); const c = document.getElementById('anime-player-container'); if (c) { var spriteUrl = d.sprite_url ? d.sprite_url : null; window.b2PlayerOptions = { sources: d.stream_urls, gdriveSources: gdSrcs, episodeId: d.id, prevUrl: d.prev_url, nextUrl: d.next_url, skipIntroAt: null, posterUrl: d.poster_url, title: epTitle, slug: slug, currentEp: d.episode_number, episodes: window.b2PlayerOptions?.episodes || [], epTotal: window.b2PlayerOptions?.epTotal || 0, epPerPage: window.b2PlayerOptions?.epPerPage || 50, epCurrentPage: window.b2PlayerOptions?.epCurrentPage || 1, logoUrl: window.b2PlayerOptions?.logoUrl || null, spriteUrl: spriteUrl, }; var _pp = window.b2PlayerOptions.epPerPage || 52; var _eps = window.b2PlayerOptions.episodes || []; var _epIdx = _eps.findIndex(function(e) { return e.id === d.id; }); window.b2PlayerOptions.epCurrentPage = _epIdx >= 0 ? Math.floor(_epIdx / _pp) + 1 : 1; } this.gdriveSources = gdSrcs; if (window.b2PlayerOptions) window.b2PlayerOptions.hlsUrl = d.hls_url || null; // Resolve the target server BEFORE touching any player, otherwise the // previous episode keeps playing inside a display:none frame (double audio). var order = (this.server === 'hls') ? ['hls', 'b2', 'gdrive'] : ['b2', 'gdrive', 'hls']; var picked = null; for (var oi = 0; oi < order.length; oi++) { if (order[oi] === 'b2' && canB2) { picked = 'b2'; break; } if (order[oi] === 'gdrive' && canGd) { picked = 'gdrive'; break; } if (order[oi] === 'hls' && canHls) { picked = 'hls'; break; } } if (!picked) picked = canB2 ? 'b2' : (canGd ? 'gdrive' : (canHls ? 'hls' : this.server)); this.server = picked; this.pauseInactivePlayers(); // Player langsung mencoba primary GDrive. Kalau kena 403, // player.js (_handleFailure) yang menampilkan overlay dan // memicu mirror on-demand — jadi pindah episode tidak lagi // tertahan menunggu mirror dibuat. if (picked === 'hls' || (!canB2 && !canGd)) { this.killDirectPlayer(); } else if (c) { var gdNow = (picked === 'gdrive'); var srces = gdNow ? gdSrcs : d.stream_urls; if (gdNow) this.gdriveLoaded = false; else this.b2Loaded = false; if (c._player && c._player.switchSource) { c._player.isGdrive = gdNow; c._player.switchSource( srces, d.prev_url, d.next_url, d.poster_url, epTitle, slug, window.b2PlayerOptions.episodes, d.episode_number, window.b2PlayerOptions.epCurrentPage, window.b2PlayerOptions.epPerPage, window.b2PlayerOptions.epTotal, d.id, spriteUrl ); const v = c.querySelector('#anime-video'); if (v) { let _done = false; const _ready = () => { if (_done) return; _done = true; if (gdNow) this.gdriveLoaded = true; else this.b2Loaded = true; }; v.addEventListener('playing', _ready, { once: true }); v.addEventListener('canplay', _ready, { once: true }); setTimeout(_ready, 8000); } else { if (gdNow) this.gdriveLoaded = true; else this.b2Loaded = true; } } else { c.querySelectorAll('video').forEach((v) => this._hardStopMedia(v)); c.innerHTML = ''; this.$nextTick(() => { if (gdNow) window.initAnimePlayer(c, Object.assign({}, window.b2PlayerOptions, { sources: srces, isGdrive: true })); else window.initAnimePlayer(c, window.b2PlayerOptions); if (gdNow) this.gdriveLoaded = true; else this.b2Loaded = true; }); } } // HLS player: (re)source it only after the server is resolved. if (this.server === 'hls') { this.hlsLoaded = false; const hc = document.getElementById('hls-player-container'); // A new episode is an explicit play intent -- unless the // user paused while this switch was still in flight. if (hc && (hc._hlsPauseEpoch || 0) === hcEp0) hc._hlsUserPaused = false; if (!canHls) { this.killHlsPlayer(); } else if (hc && typeof hc.switchHlsSource === 'function') { hc.switchHlsSource(d.hls_url); this.hlsLoaded = true; } else { this.$nextTick(() => this.loadHls()); } } else { this._pauseHls(); } // 1. Release date if (this.$refs.epReleaseDate) { var dt = this.$refs.epReleaseDate; if (d.formatted_release_date) { dt.querySelector('span') ? dt.querySelector('span').textContent = d.formatted_release_date : dt.appendChild(document.createTextNode(d.formatted_release_date)); dt.style.display = ''; } else { dt.style.display = 'none'; } } // 3. Duration if (this.$refs.epDuration) { if (d.duration) { this.$refs.epDuration.querySelector('span').textContent = d.duration; this.$refs.epDuration.style.display = ''; } else { this.$refs.epDuration.style.display = 'none'; } } // 4. Description if (this.$refs.epDescription) { var descP = this.$refs.epDescription.querySelector('p'); if (descP) { if (d.description) { descP.innerHTML = 'Episode ' + epLabel + ' - ' + d.description; this.$refs.epDescription.style.display = ''; } else { this.$refs.epDescription.style.display = 'none'; } } } // 5. Like button var likeBtn = document.getElementById('like-btn'); if (likeBtn) { likeBtn.dataset.episodeId = d.id; likeBtn.dataset.liked = d.is_liked ? '1' : '0'; var lc = document.getElementById('like-count'); if (lc) lc.textContent = d.likes_count || '0'; var icon = likeBtn.querySelector('svg'); if (d.is_liked) { likeBtn.classList.add('liked'); if (icon) icon.setAttribute('fill', 'currentColor'); } else { likeBtn.classList.remove('liked'); if (icon) icon.setAttribute('fill', 'none'); } } // 7. Update current episode ID for pagination this.currentEpisodeId = d.id; // 9. HLS / GDrive / B2 tabs — source + player already resolved above this.hasHls = canHls; this.hasGdrive = canGd; this.hasB2Stream = canB2; if (this._wasFullscreen && this._prevServer !== this.server) { const target = this._isDirect() ? document.getElementById('anime-player-container') : document.getElementById('hls-player-container'); this._reenterFullscreen(target, 0); } var posterOverlays = document.querySelectorAll('.watch-player-frame [style*="background-image"]'); if (d.poster_url) { for (var i = 0; i < posterOverlays.length; i++) { posterOverlays[i].style.backgroundImage = 'url(\'' + d.poster_url + '\')'; } } // 10. Prev/Next buttons if (this.$refs.prevBtn) { if (d.prev_url) { this.$refs.prevBtn.href = d.prev_url; this.$refs.prevBtn.classList.remove('hidden'); } else { this.$refs.prevBtn.classList.add('hidden'); } } if (this.$refs.nextBtn) { if (d.next_url) { this.$refs.nextBtn.href = d.next_url; this.$refs.nextBtn.classList.remove('hidden'); } else { this.$refs.nextBtn.classList.add('hidden'); } } // 11. Browser URL history.pushState(null, '', '/anime/' + slug + '/episode/' + d.episode_number); // 12. Breadcrumb episode var breadcrumbEpisode = document.querySelector('#watch-breadcrumb .crumb-seg:last-child .crumb-label'); if (breadcrumbEpisode) { var isMovieAnime = false; breadcrumbEpisode.textContent = isMovieAnime ? 'Movie' : 'Ep ' + epLabel; } // 13. Episode chips active state document.querySelectorAll('.ep-chip').forEach(function(el) { el.classList.remove('active'); if (parseInt(el.dataset.ep) === d.episode_number) { el.classList.add('active'); } }); // 12b. Full grid items active state (showAllEpisodes) document.querySelectorAll('.ep-btn, .ep-btn-sidebar').forEach(function(el) { if (parseInt(el.dataset.ep) === d.episode_number) { el.classList.add('bg-purple-600', 'text-white'); el.classList.remove('bg-gray-800', 'text-gray-400', 'border', 'border-gray-700/50', 'hover:bg-gray-700', 'bg-gray-700/50'); } else { el.classList.remove('bg-purple-600', 'text-white'); el.classList.add('bg-gray-800', 'text-gray-400', 'border', 'border-gray-700/50', 'hover:bg-gray-700'); } }); // 13. Sidebar episodes active state document.querySelectorAll('.sidebar-ep-item').forEach(function(el) { el.classList.remove('active', 'bg-purple-600/10'); el.classList.add('hover:bg-white/5'); if (parseInt(el.dataset.ep) === d.episode_number) { el.classList.remove('hover:bg-white/5'); el.classList.add('active', 'bg-purple-600/10'); } }); // 14. Repost button var rpBtn = document.getElementById('repost-btn'); if (rpBtn) rpBtn.dataset.episodeId = d.id; // 15. Download link var dlLink = document.getElementById('download-link'); if (dlLink) dlLink.href = '/anime/' + slug + '/episode/' + d.episode_number + '/download'; // 16. Report forms document.querySelectorAll('.report-form').forEach(function(f) { f.action = '/episode/' + d.id + '/report'; }); // 17. Comments if (d.comments_html) { var csEl = document.getElementById('comment-section'); if (csEl) csEl.outerHTML = d.comments_html; } // 18. Episode Berikutnya var nexEl = document.getElementById('next-episode-container'); if (nexEl) { nexEl.innerHTML = d.next_episode_html || ''; nexEl.hidden = !(d.next_episode_html || '').trim(); } // Safety net: only the resolved server may keep playing. this.pauseInactivePlayers(); this._loading = false; }) .catch(() => { this._loading = false; }); }, // Keluar dari fullscreen (native maupun fallback CSS) pada player // selain `keep`. _exitOtherFullscreens(keep) { const keepPlayer = keep ? (keep._player ? keep._player.player : keep._hlsPlayer) : null; const keepTarget = keepPlayer && keepPlayer.fullscreen ? keepPlayer.fullscreen.target : null; ['anime-player-container', 'hls-player-container'].forEach((id) => { const oc = document.getElementById(id); if (!oc || oc === keep) return; const op = oc._player ? oc._player.player : oc._hlsPlayer; try { if (!op || !op.fullscreen || !op.fullscreen.active) return; // Target fullscreen sama (`.player-fs-shell` dipakai bersama // kedua player) -> JANGAN di-exit; itu justru menutup // fullscreen yang sedang aktif. if (keepTarget && op.fullscreen.target === keepTarget) return; op.fullscreen.exit(); } catch (e) {} }); }, _reenterFullscreen(container, attempts) { if (!container) return; attempts = attempts || 0; if (attempts > 60) return; const retry = (delay) => setTimeout(() => this._reenterFullscreen(container, attempts + 1), delay || 200); const pe = container.querySelector('.plyr'); const p = container._player ? (container._player.player || null) : (container._hlsPlayer || null); if (!p || !p.fullscreen) { retry(); return; } // Sudah fullscreen di player ini (native atau fallback CSS)? if (p.fullscreen.active) { const nf = document.fullscreenElement; if (!nf || !pe || nf === pe || pe.contains(nf) || nf.contains(pe)) return; } // Player yang baru ditinggalkan harus keluar dulu -- baik native // (document.fullscreenElement) maupun fallback CSS (class), karena // di mode fallback document.fullscreenElement selalu null. this._exitOtherFullscreens(container); // Native: tunggu sampai browser benar-benar melepas fullscreen. if (document.fullscreenElement) { retry(); return; } // Frame tujuan harus sudah ter-render (Alpine x-show), kalau tidak // fullscreen ke elemen yang belum tampil akan kosong. const frame = container.closest('.watch-player-frame'); if (frame && window.getComputedStyle(frame).display === 'none') { retry(); return; } if (!pe) { retry(); return; } // Plyr's fullscreen.enter() TIDAK mengembalikan promise -> jangan pakai // .catch() (dulu melempar TypeError dan bikin re-enter tak pernah jalan). // requestFullscreen juga bisa ditolak (butuh user gesture), jadi hasilnya // dipantau lewat retry, bukan dianggap sukses begitu saja. try { if (!p.fullscreen.active) p.fullscreen.enter(); } catch (e) { retry(300); return; } retry(300); }, loadPage(page) { if (this._loadingGrid) return; this._loadingGrid = true; const params = new URLSearchParams({ page: page || 1, ep: this.currentEpisodeId, sort: this.epSort, search: this.epSearch }); fetch('/anime/boruto-naruto-next-generations/episodes/grid?' + params.toString()) .then(r => r.json()) .then(d => { if (this.$refs.sidebarEpList) this.$refs.sidebarEpList.innerHTML = d.sidebar_episodes; if (this.$refs.sidebarPag) this.$refs.sidebarPag.innerHTML = d.pagination; this._loadingGrid = false; }) .catch(() => { this._loadingGrid = false; }); }, applyEpSearch() { this.loadPage(1); } }" class="">
EP 148 - A New Mission!!

Laporkan Masalah

Pilih alasan untuk melaporkan episode ini.

Laporkan Masalah

Jelaskan masalah yang kamu temui agar tim kami bisa memperbaikinya.

Boruto: Naruto Generasi Selanjutnya

6.0 · TV · Complete
Boruto: Naruto Next Generations - Naruto was a young shinobi with an incorrigible knack for mischief. He achieved his dream to become the greatest ninja in the village and his face sits atop the Hokage monument. But this is not his story... A new generation of ninja are ready to take the stage, led by Naruto's own son, Boruto!

(Source: VIZ Media)

Nonton Boruto: Naruto Next Generations Episode 148 Subtitle Indonesia secara online dengan berbagai pilihan kualitas video, mulai dari 360p, 480p, 720p hingga 1080p. Pilih server dan resolusi yang sesuai untuk menikmati episode Boruto: Naruto Next Generations dengan subtitle Indonesia di perangkat kamu.

Studio Pierrot

Komentar (0)

atau untuk berkomentar.

Belum ada komentar. Jadilah yang pertama!

Pilih lagu untuk diputar

· NC

Belum ada theme songs

Daftar Episode

EP 1

EP 1

Boruto Uzumaki!

EP 2

EP 2

The Hokage's Son!

EP 3

EP 3

Metal Lee Goes Wild!

EP 4

EP 4

A Ninjutsu Battle of the Sexes!

EP 5

EP 5

The Mysterious Transfer Student!

EP 6

EP 6

The Final Lesson!

EP 7

EP 7

Love and Potato Chips!

EP 8

EP 8

The Dream's Revelation

EP 9

EP 9

Proof of Oneself

EP 10

EP 10

The Ghost Incident: The Investigation Begins!

EP 11

EP 11

The Shadow of the Mastermind

EP 12

EP 12

Boruto and Mitsuki

EP 13

EP 13

The Demon Beast Appears!

EP 14

EP 14

The Path That Boruto Can See

EP 15

EP 15

A New Path

EP 16

EP 16

Crisis: The Threat of Failing!

EP 17

EP 17

Run, Sarada!

EP 18

EP 18

A Day in The Life of the Uzumaki Family

EP 19

EP 19

Sarada Uchiha

EP 20

EP 20

The Boy With The Sharingan

EP 21

EP 21

Sasuke and Sarada

EP 22

EP 22

Connected Feelings

EP 23

EP 23

Bonds Come In All Shapes

EP 24

EP 24

Boruto and Sarada

EP 25

EP 25

The Turbulent Field Trip

EP 26

EP 26

The Mizukage's Successor

EP 27

EP 27

A Shinobi Bout of Friendship

EP 28

EP 28

Declaration of War

EP 29

EP 29

The New Seven Ninja Swordsmen!

EP 30

EP 30

The Sharingan vs. The Lightning Blade, Kiba the Fang!

EP 31

EP 31

Boruto and Kagura

EP 32

EP 32

The Quest for Souvenirs

EP 33

EP 33

The Super Beast Scroll Slump!

EP 34

EP 34

The Night of the Shooting Stars

EP 35

EP 35

The Parent Teacher Conference!

EP 36

EP 36

The Graduation Exam Begins!

EP 37

EP 37

A Shinobi's Resolve

EP 38

EP 38

Formation of the Three-Man Squad?

EP 39

EP 39

The Path Lit by the Full Moon

EP 40

EP 40

Team 7: The First Mission!

EP 41

EP 41

Strength in Unity

EP 42

EP 42

A Ninja's Job

EP 43

EP 43

The Byakuya Gang Surfaces!

EP 44

EP 44

Shikadai's Doubts

EP 45

EP 45

Memories from the Day of Snow

EP 46

EP 46

Go! The Crest of Night Strategy

EP 47

EP 47

The Figure I Want to Be

EP 48

EP 48

The Genin Documentary

EP 49

EP 49

Wasabi and Namida

EP 50

EP 50

The Chunin Exams: The Recommendation Meeting

EP 51

EP 51

Boruto's Birthday

EP 52

EP 52

Sasuke's Shadow

atau login dengan email

Lupa password?
atau daftar dengan email

Username ini sudah dipakai. Pilih username lain.

Hanya huruf kecil, angka, dan underscore (_) tanpa spasi.

Username tersedia!