PornXnow Video Downloader

Download videos from pornxnow.me with one click

Size

8.1 KB

Version

1.0.1

Created

Oct 25, 2025

Updated

20 days ago

1// ==UserScript==
2// @name		PornXnow Video Downloader
3// @description		Download videos from pornxnow.me with one click
4// @version		1.0.1
5// @match		https://*.pornxnow.me/*
6// @icon		https://pornxnow.me/wp-content/uploads/2019/05/cropped-favicon-pornxnow-32x32.png
7// @grant		GM.xmlhttpRequest
8// @connect		pxnw.xyz
9// @connect		*.pxnw.xyz
10// ==/UserScript==
11(function() {
12    'use strict';
13
14    console.log('PornXnow Video Downloader initialized');
15
16    // Debounce function to prevent multiple rapid calls
17    function debounce(func, wait) {
18        let timeout;
19        return function executedFunction(...args) {
20            const later = () => {
21                clearTimeout(timeout);
22                func(...args);
23            };
24            clearTimeout(timeout);
25            timeout = setTimeout(later, wait);
26        };
27    }
28
29    // Function to extract video URL from iframe
30    async function extractVideoUrl(iframeSrc) {
31        try {
32            console.log('Fetching iframe content from:', iframeSrc);
33            
34            const response = await GM.xmlhttpRequest({
35                method: 'GET',
36                url: iframeSrc,
37                headers: {
38                    'Referer': window.location.href
39                }
40            });
41
42            const html = response.responseText;
43            console.log('Iframe content fetched successfully');
44
45            // Try to find video URL in various formats
46            let videoUrl = null;
47
48            // Method 1: Look for direct video sources
49            const videoSourceMatch = html.match(/sources:\s*\[\s*{[^}]*file:\s*["']([^"']+\.mp4[^"']*)["']/i);
50            if (videoSourceMatch) {
51                videoUrl = videoSourceMatch[1];
52            }
53
54            // Method 2: Look for file: property
55            if (!videoUrl) {
56                const fileMatch = html.match(/file:\s*["']([^"']+\.mp4[^"']*)["']/i);
57                if (fileMatch) {
58                    videoUrl = fileMatch[1];
59                }
60            }
61
62            // Method 3: Look for video tag src
63            if (!videoUrl) {
64                const videoTagMatch = html.match(/<video[^>]+src=["']([^"']+)["']/i);
65                if (videoTagMatch) {
66                    videoUrl = videoTagMatch[1];
67                }
68            }
69
70            // Method 4: Look for any .mp4 URL
71            if (!videoUrl) {
72                const mp4Match = html.match(/(https?:\/\/[^"'\s]+\.mp4[^"'\s]*)/i);
73                if (mp4Match) {
74                    videoUrl = mp4Match[1];
75                }
76            }
77
78            if (videoUrl) {
79                // Clean up the URL
80                videoUrl = videoUrl.replace(/\\/g, '');
81                console.log('Video URL found:', videoUrl);
82                return videoUrl;
83            } else {
84                console.error('Could not find video URL in iframe content');
85                return null;
86            }
87        } catch (error) {
88            console.error('Error extracting video URL:', error);
89            return null;
90        }
91    }
92
93    // Function to create download button
94    function createDownloadButton() {
95        console.log('Creating download button');
96
97        // Find the video player container
98        const videoWrapper = document.querySelector('.video-wrapper');
99        if (!videoWrapper) {
100            console.error('Video wrapper not found');
101            return;
102        }
103
104        // Check if button already exists
105        if (document.getElementById('custom-video-downloader')) {
106            console.log('Download button already exists');
107            return;
108        }
109
110        // Create download button container
111        const downloadContainer = document.createElement('div');
112        downloadContainer.id = 'custom-video-downloader';
113        downloadContainer.style.cssText = `
114            margin: 15px 0;
115            padding: 15px;
116            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
117            border-radius: 8px;
118            text-align: center;
119            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
120        `;
121
122        // Create download button
123        const downloadButton = document.createElement('button');
124        downloadButton.id = 'download-video-btn';
125        downloadButton.innerHTML = '<i class="fa fa-download"></i> Download Video (HD)';
126        downloadButton.style.cssText = `
127            background: #fff;
128            color: #667eea;
129            border: none;
130            padding: 12px 30px;
131            font-size: 16px;
132            font-weight: bold;
133            border-radius: 5px;
134            cursor: pointer;
135            transition: all 0.3s ease;
136            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
137        `;
138
139        downloadButton.onmouseover = function() {
140            this.style.transform = 'scale(1.05)';
141            this.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
142        };
143
144        downloadButton.onmouseout = function() {
145            this.style.transform = 'scale(1)';
146            this.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)';
147        };
148
149        downloadButton.onclick = async function() {
150            const originalText = this.innerHTML;
151            this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> Extracting video...';
152            this.disabled = true;
153
154            try {
155                // Get iframe source
156                const iframe = document.querySelector('.responsive-player iframe');
157                if (!iframe || !iframe.src) {
158                    throw new Error('Video iframe not found');
159                }
160
161                const videoUrl = await extractVideoUrl(iframe.src);
162                
163                if (videoUrl) {
164                    this.innerHTML = '<i class="fa fa-check"></i> Opening download...';
165                    
166                    // Open video in new tab for download
167                    GM.openInTab(videoUrl, false);
168                    
169                    setTimeout(() => {
170                        this.innerHTML = originalText;
171                        this.disabled = false;
172                    }, 2000);
173                } else {
174                    throw new Error('Could not extract video URL');
175                }
176            } catch (error) {
177                console.error('Download error:', error);
178                this.innerHTML = '<i class="fa fa-exclamation-triangle"></i> Error - Try again';
179                this.style.background = '#ff6b6b';
180                this.style.color = '#fff';
181                
182                setTimeout(() => {
183                    this.innerHTML = originalText;
184                    this.style.background = '#fff';
185                    this.style.color = '#667eea';
186                    this.disabled = false;
187                }, 3000);
188            }
189        };
190
191        downloadContainer.appendChild(downloadButton);
192
193        // Insert after video player
194        const videoPlayer = videoWrapper.querySelector('.responsive-player');
195        if (videoPlayer && videoPlayer.nextSibling) {
196            videoWrapper.insertBefore(downloadContainer, videoPlayer.nextSibling);
197        } else {
198            videoWrapper.appendChild(downloadContainer);
199        }
200
201        console.log('Download button created successfully');
202    }
203
204    // Initialize the extension
205    function init() {
206        console.log('Initializing video downloader');
207
208        // Wait for page to load
209        if (document.readyState === 'loading') {
210            document.addEventListener('DOMContentLoaded', init);
211            return;
212        }
213
214        // Check if we're on a video page
215        const videoWrapper = document.querySelector('.video-wrapper');
216        if (!videoWrapper) {
217            console.log('Not a video page, extension will not run');
218            return;
219        }
220
221        // Wait a bit for iframe to load
222        setTimeout(() => {
223            createDownloadButton();
224        }, 2000);
225
226        // Observe DOM changes in case content loads dynamically
227        const observer = new MutationObserver(debounce(() => {
228            if (!document.getElementById('custom-video-downloader')) {
229                createDownloadButton();
230            }
231        }, 1000));
232
233        observer.observe(document.body, {
234            childList: true,
235            subtree: true
236        });
237    }
238
239    // Start the extension
240    init();
241})();
PornXnow Video Downloader | Robomonkey