Skip to content

Commit

Permalink
add main project files
Browse files Browse the repository at this point in the history
  • Loading branch information
henrique-coder committed Jan 22, 2024
1 parent e94ea86 commit 51a313a
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 0 deletions.
141 changes: 141 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SyncGroove</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="header">
<h1>SyncGroove</h1>
</div>

<div class="container">
<div class="input-container">
<input type="text" id="urlInput" placeholder="Enter YouTube video URL">
<button onclick="getVideoInfo()">Retrieve Information</button>
</div>

<div id="result" class="result-container"></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
const { ipcRenderer } = require('electron');

document.addEventListener('DOMContentLoaded', () => {
toggleSection('GeneralInformation');
});

function getVideoInfo() {
const urlInput = document.getElementById('urlInput').value;
ipcRenderer.send('getVideoInfo', urlInput);
}

ipcRenderer.on('videoInfo', (event, result) => {
document.getElementById('result').innerHTML = formatResult(result);
});

ipcRenderer.on('openExternalLink', (event, link) => {
shell.openExternal(link);
});

function formatResult(result) {
if (result.error) {
return `<p>Error: ${result.error}</p>`;
}

let formattedResult = '<div class="category" onclick="toggleSection(\'GeneralInformation\')">General Information</div>';
formattedResult += '<ul id="GeneralInformation" class="section">';

const generalInfoKeys = ['URL', 'ID', 'Title', 'Channel', 'Duration', 'Views count', 'Likes count', 'Comments count', 'Tags', 'Categories', 'Age restricted', 'Upload date'];

for (const key of generalInfoKeys) {
if (result.output.data.info[key.toLowerCase()] !== undefined) {
const niceKey = key.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
const value = key === 'Duration' ? formatDuration(result.output.data.info[key.toLowerCase()]) : result.output.data.info[key.toLowerCase()] || 'None';
formattedResult += `<li><strong>${niceKey}:</strong> ${value}</li>`;
}
}

formattedResult += '</ul>';

if (result.output.data.media.video && result.output.data.media.video.length > 0) {
formattedResult += '<div class="category" onclick="toggleSection(\'VideoDirectURLs\')">Video Direct URLs</div>';
formattedResult += '<ul id="VideoDirectURLs" class="section" style="display:none;">';

result.output.data.media.video.sort((a, b) => compareQualities(a.quality, b.quality)).reverse().forEach((video) => {
const videoInfo = `${video.quality} - ${video.bitrate} kbps - ${video.codec} - ${formatBytes(video.size)}`;
formattedResult += `<li><a href="#" onclick="openLink('${video.url}')">${videoInfo}</a></li>`;
});

formattedResult += '</ul>';
}

if (result.output.data.media.audio && result.output.data.media.audio.length > 0) {
formattedResult += '<div class="category" onclick="toggleSection(\'AudioDirectURLs\')">Audio Direct URLs</div>';
formattedResult += '<ul id="AudioDirectURLs" class="section" style="display:none;">';

result.output.data.media.audio.sort((a, b) => b.bitrate - a.bitrate).forEach((audio) => {
const audioInfo = `${audio.bitrate} kbps - ${audio.codec} - ${formatBytes(audio.size)}`;
formattedResult += `<li><a href="#" onclick="openLink('${audio.url}')">${audioInfo}</a></li>`;
});

formattedResult += '</ul>';
}

if (result.output.data.media.subtitles && result.output.data.media.subtitles.length > 0) {
formattedResult += '<div class="category" onclick="toggleSection(\'SubtitleDirectURLs\')">Subtitle Direct URLs</div>';
formattedResult += '<ul id="SubtitleDirectURLs" class="section" style="display:none;">';

result.output.data.media.subtitles.sort((a, b) => a.lang.localeCompare(b.lang)).forEach((subtitle) => {
const subtitleInfo = `${subtitle.lang} - ${subtitle.ext}`;
formattedResult += `<li><a href="#" onclick="openLink('${subtitle.url}')">${subtitleInfo}</a></li>`;
});

formattedResult += '</ul>';
}

return formattedResult;
}

function formatBytes(bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 Byte';
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}

function compareQualities(qualityA, qualityB) {
const order = ['4320p', '2160p', '1440p', '1080p', '720p', '480p', '360p', '240p', '144p'];
return order.indexOf(qualityB) - order.indexOf(qualityA);
}

function formatDuration(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainingSeconds = seconds % 60;
return `${pad(hours)}:${pad(minutes)}:${pad(remainingSeconds)}`;
}

function pad(value) {
return value < 10 ? `0${value}` : value;
}

function toggleSection(sectionId) {
const sections = document.querySelectorAll('.section');
sections.forEach((section) => {
section.style.display = 'none';
});

const section = document.getElementById(sectionId);
section.style.display = 'block';
}

function openLink(link) {
ipcRenderer.send('openExternalLink', link);
}
</script>
</body>
</html>
59 changes: 59 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const { app, BrowserWindow, ipcMain, shell } = require('electron');
const axios = require('axios');

let mainWindow;

function createWindow() {
mainWindow = new BrowserWindow({
width: 700,
height: 700,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});

mainWindow.loadFile('index.html');
mainWindow.removeMenu();
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

function extractVideoId(url) {
const regex = /(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
const match = url.match(regex);
return match ? match[1] : null;
}

ipcMain.on('getVideoInfo', async (event, url) => {
const videoId = extractVideoId(url);

if (videoId) {
try {
const response = await axios.get(`http://node1.mindwired.com.br:8452/api/wrapper/v1/youtube-video?id=${videoId}`);
event.reply('videoInfo', response.data);
} catch (error) {
console.error(`Error fetching video information: ${error.message}`);
event.reply('videoInfo', { error: `Error fetching video information: ${error.message}` });
}
} else {
console.error('Invalid video URL');
event.reply('videoInfo', { error: 'Invalid video URL' });
}
});

ipcMain.on('openExternalLink', (event, link) => {
shell.openExternal(link);
});
94 changes: 94 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #fff;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
overflow: hidden;
}

.header {
width: 100%;
text-align: center;
padding: 20px 0;
background-color: #7289da;
color: #fff;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}

.container {
width: 80%;
max-width: 400px;
text-align: left;
margin: auto;
border-radius: 10px;
overflow: hidden;
background-color: #fff;
}

.input-container {
margin-bottom: 10px;
text-align: center;
}

.input-container input,
.input-container button {
margin-bottom: 10px;
padding: 10px;
font-size: 16px;
border-radius: 5px;
}

.input-container button {
background-color: #7289da;
color: #fff;
border: none;
cursor: pointer;
transition: background-color 0.3s;
border-radius: 5px;
}

.input-container button:hover {
background-color: #677bc4;
}

.result-container {
white-space: pre-wrap;
max-height: 400px;
overflow-y: auto;
padding: 10px;
border-radius: 5px;
}

.category {
font-size: 18px;
font-weight: bold;
margin-top: 15px;
cursor: pointer;
background-color: #7289da;
color: #fff;
padding: 5px 10px;
border-bottom: 1px solid #fff;
}

.section {
list-style-type: none;
padding: 0;
background-color: #f2f2f2;
padding: 10px;
border-bottom: 1px solid #ddd;
display: none;
}

.section li {
margin-top: 5px;
}

.collapsed {
display: none;
}

0 comments on commit 51a313a

Please sign in to comment.