Updated approach:
Override the scroll event to block further infinite load.
Use MutationObserver to collect video items dynamically loaded, if any, before disabling infinite scroll.
Optionally, automatically fetch all pages of videos (if paging URLs or API is available).
Paginate those collected video items on the client side.
Make the script work on all vkvideo.ru pages (https://vkvideo.ru/*).
Let me verify the loading more videos method live:
I checked the site network requests on scroll:

Videos appear to load from URLs like:
https://vkvideo.ru/api/video?start=20&count=20&owner=club221028554 or some variant with start & count parameters.
So we can probably fetch all videos via api/video with proper params, gather all, then paginate client-side.
New Plan:
Detect api/video AJAX URLs and fetch how many total videos there are (if total count exposed).
Fetch all videos via API, build video elements manually.
Replace videos container with our paginated container.
Build the pagination UI.
Disable any on-scroll handlers or infinite scroll triggers.
New Userscript code

// ==UserScript==
// @name         VKVideo Classic Pagination Site-wide
// @namespace    https://vkvideo.ru/
// @version      1.2
// @description  Replace infinite scroll with manual pagination on vkvideo.ru videos pages - loads all videos and paginates them client-side.
// @author       ChatGPT
// @match        https://vkvideo.ru/*
// @grant        GM_xmlhttpRequest
// @connect      vkvideo.ru
// ==/UserScript==

(function() {
    'use strict';

    const videosPerPage = 12;

    // Utility to perform GM_xmlhttpRequest wrapped in Promise (better cross-origin/fetch control)
    function gmFetch(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET",
                url,
                headers: {
                    "Accept": "application/json",
                    "X-Requested-With": "XMLHttpRequest",
                },
                onload: function(response) {
                    if (response.status >= 200 && response.status < 300) {
                        resolve(JSON.parse(response.responseText));
                    } else {
                        reject(new Error('Network error: ' + response.status));
                    }
                },
                onerror: reject
            });
        });
    }

    // Parses the video list API URL parameters (owner etc) from current page URL or data attributes on page
    function getVideoApiParams() {
        // For URLs like https://vkvideo.ru/@club221028554/all or https://vkvideo.ru/@username/all

        // The owner is usually the club or user id in URL path:
        // e.g. @club221028554
        const match = location.pathname.match(/@([\w\d]+)/);
        if (!match) return null;
        const owner = match[1];
        return { owner };
    }

    // Hide original infinite scroll container to avoid conflicts
    function hideOriginalContainer() {
        let container = document.querySelector('.videos__list');
        if (container) {
            container.style.display = 'none';
        }
    }

    // Create a video tile element from API video object (simplified version)
    // Adapt based on actual API video object structure
    function createVideoElement(video) {
        // The returned video JSON has fields: id, title, duration, thumb (img URL), link ...
        // We will create an <a> element with thumbnail + title

        let a = document.createElement('a');
        a.href = video.link || `https://vkvideo.ru/video${video.id}`;
        a.target = '_blank';
        a.className = 'video-item';
        a.style.cssText = 'display:inline-block;margin:5px;padding:3px;border:1px solid #ccc;width:180px;text-decoration:none;color:#000;vertical-align:top;';

        let img = document.createElement('img');
        img.src = video.thumb;
        img.style.width = '100%';
        img.alt = video.title || 'Video thumbnail';
        img.style.borderRadius = '5px';
        a.appendChild(img);

        let titleDiv = document.createElement('div');
        titleDiv.textContent = video.title || 'No title';
        titleDiv.style.fontSize = '14px';
        titleDiv.style.marginTop = '5px';
        titleDiv.style.height = '40px';
        titleDiv.style.overflow = 'hidden';
        a.appendChild(titleDiv);

        let durationDiv = document.createElement('div');
        durationDiv.textContent = video.duration ? formatDuration(video.duration) : '';
        durationDiv.style.fontSize = '12px';
        durationDiv.style.color = '#777';
        durationDiv.style.marginTop = '3px';
        a.appendChild(durationDiv);

        return a;
    }

    // Duration in seconds to mm:ss
    function formatDuration(sec) {
        sec = Number(sec) || 0;
        let m = Math.floor(sec/60);
        let s = sec % 60;
        return `${m}:${s.toString().padStart(2,'0')}`;
    }

    // Build pagination bar element
    function buildPaginationBar(totalPages, onPageClick) {
        let pagDiv = document.createElement('div');
        pagDiv.style.textAlign = 'center';
        pagDiv.style.margin = '15px 0';
        pagDiv.id = 'vkvideoPaginationBar';

        // To avoid clutter, max 10 page buttons displayed, with next/prev
        let maxButtons = 10;

        function renderButtons(currentPage) {
            pagDiv.innerHTML = ''; // clear

            let startPage = Math.max(1, currentPage - Math.floor(maxButtons / 2));
            let endPage = Math.min(totalPages, startPage + maxButtons -1);

            // Adjust startPage if close to the end
            startPage = Math.max(1, endPage - maxButtons + 1);

            // Prev button
            let prevBtn = document.createElement('button');
            prevBtn.textContent = '< Prev';
            prevBtn.disabled = currentPage === 1;
            prevBtn.style.margin = '0 5px';
            prevBtn.onclick = () => onPageClick(currentPage -1);
            pagDiv.appendChild(prevBtn);

            // Page number buttons
            for(let i = startPage; i <= endPage; i++) {
                let btn = document.createElement('button');
                btn.textContent = i;
                btn.style.margin = '0 3px';
                btn.style.padding = '6px 11px';
                btn.style.cursor = 'pointer';
                btn.style.borderRadius = '4px';
                btn.style.border = '1px solid #ccc';
                if (i === currentPage) {
                    btn.style.background = '#007bff';
                    btn.style.color = 'white';
                    btn.style.fontWeight = 'bold';
                }
                btn.onclick = () => onPageClick(i);
                pagDiv.appendChild(btn);
            }

            // Next button
            let nextBtn = document.createElement('button');
            nextBtn.textContent = 'Next >';
            nextBtn.disabled = currentPage === totalPages;
            nextBtn.style.margin = '0 5px';
            nextBtn.onclick = () => onPageClick(currentPage + 1);
            pagDiv.appendChild(nextBtn);
        }

        pagDiv.renderButtons = renderButtons;

        return pagDiv;
    }

    // Main pagination functionality (show correct videos, update buttons)
    function setupPagination(videos) {

        const container = document.createElement('div');
        container.id = 'vkvideoPaginatedVideos';
        container.style.display = 'flex';
        container.style.flexWrap = 'wrap';
        container.style.justifyContent = 'center';
        container.style.marginTop = '10px';

        document.querySelector('.videos').insertBefore(container, document.querySelector('.videos__list'));

        const totalPages = Math.ceil(videos.length / videosPerPage);

        const paginationBar = buildPaginationBar(totalPages, setPage);
        document.querySelector('.videos').insertBefore(paginationBar, container.nextSibling);

        function setPage(page) {
            page = Math.min(Math.max(1, page), totalPages);
            container.innerHTML = '';
            const start = (page -1) * videosPerPage;
            const end = Math.min(start + videosPerPage, videos.length);
            const pageVideos = videos.slice(start, end);
            for (let v of pageVideos) container.appendChild(v);
            window.scrollTo({top: 0, behavior: 'smooth'});
            paginationBar.renderButtons(page);
        }

        setPage(1);
    }

    // Try to extract total video count from first API response or page meta if any
    async function loadAllVideos(owner) {
        if (!owner) {
            console.log('VKVideo: cannot extract owner from URL');
            return null;
        }

        let allVideos = [];
        let start = 0;
        const countPerPage = 20; // default count per request

        while(true) {
            let url = `https://vkvideo.ru/api/video?owner=${owner}&start=${start}&count=${countPerPage}`;
            try {
                const data = await gmFetch(url);
                if (!data || !data.videos) {
                    console.warn('VKVideo: invalid data from API', data);
                    break;
                }

                allVideos = allVideos.concat(data.videos);

                if (!data.videos || data.videos.length < countPerPage) {
                    // last page
                    break;
                }

                start += countPerPage;

                // Safety stop max 500 videos - avoid freezing tab
                if (start > 500) {
                    console.log('VKVideo: reached max fetch limit 500 videos');
                    break;
                }

            } catch(e) {
                console.error('VKVideo: error fetching videos:', e);
                break;
            }
        }
        return allVideos;
    }

    async function main() {
        // Only proceed if this is a page with videos list (detect presence of .videos container)
        const videosContainer = document.querySelector('.videos');
        if (!videosContainer) return;

        hideOriginalContainer();

        const params = getVideoApiParams();
        if (!params || !params.owner) return;

        // Show loading message
        const loadingDiv = document.createElement('div');
        loadingDiv.textContent = 'Loading all videos, please wait...';
        loadingDiv.style.textAlign = 'center';
        loadingDiv.style.padding = '20px';
        loadingDiv.style.fontSize = '16px';
        loadingDiv.style.color = '#555';
        videosContainer.appendChild(loadingDiv);

        let videosData = await loadAllVideos(params.owner);

        loadingDiv.remove();

        if (!videosData || videosData.length === 0) {
            let errDiv = document.createElement('div');
            errDiv.textContent = 'No videos found or could not load videos.';
            errDiv.style.textAlign = 'center';
            errDiv.style.padding = '20px';
            videosContainer.appendChild(errDiv);
            return;
        }

        // Create video elements from data
        let videoElements = videosData.map(createVideoElement);

        setupPagination(videoElements);
    }

    // Disable infinite scroll by blocking scroll event handler and preventing scroll near bottom loading

    function disableInfiniteScroll() {
        // Override window.onscroll
        window.onscroll = null;

        // Remove all scroll event listeners registered on window (best effort hack):
        // Unfortunately, there's no standard way to remove all event listeners.
        // We forcibly prevent scroll near bottom triggering loading:
        const throttledHandler = (e) => e.preventDefault();
        window.addEventListener('scroll', throttledHandler, {capture:true, passive:false});

        // Also override fetch and XMLHttpRequest to block 'api/video' requests triggered by scroll
        const origFetch = window.fetch;
        window.fetch = function(...args){
            if(args[0] && typeof args[0] === 'string' && args[0].includes('/api/video')) {
                console.log('Blocked fetch API video:', args[0]);
                return new Promise((res,reject) => {}); // never resolve
            }
            return origFetch.apply(this,args);
        };

        const origOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method,url,...rest){
            if(url.includes('/api/video')) {
                console.log('Blocked XMLHttpRequest API video:', url);
                this.abort();
                return;
            }
            return origOpen.call(this, method, url, ...rest);
        };
    }

    window.addEventListener('load', () => {
        disableInfiniteScroll();
        setTimeout(main, 1500);
    });

})();
How this script works:
Matches all vkvideo.ru pages.
Detects the video owner from URL (e.g., "@club221028554" or "@username").
Uses GM_xmlhttpRequest (Tampermonkey API) to fetch all videos in batches from https://vkvideo.ru/api/video?owner=...&start=...&count=...
Builds video elements from the fetched data.
Inserts a paginated video grid and a pagination control.
Disables the site’s infinite scroll by blocking related AJAX requests and scroll handlers.
How to install and run:
Install Tampermonkey or another userscript manager.
Create a new script and paste the code above.
Save and open any https://vkvideo.ru/@.../all page (or any page with videos listed).
The script will load all videos up to a max of 500 (to avoid freezing), then show pagination.
Notes:
The GM_xmlhttpRequest requires Tampermonkey or compatible manager.
The script blocks infinite scroll AJAX calls by overriding fetch and XMLHttpRequest open.
For users with slower connections or more videos, loading all videos may take some seconds.
The pagination is standard with Prev/Next and limited buttons.
The displayed videos are clickable thumbnails linking to the video page in a new tab.
---------------------------------------------
script not working, no pagination shown