Open MavenW opened 1 month ago
provide code snippet you use to download video and example of video url
Hi, yes it is the code:
public List
public List<VideoFormat> getVideoFormats() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.videoFormats();
}
public List<AudioFormat> getAudioFormats() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.audioFormats();
}
public Format getBestVideoWithAudioFormat() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.bestVideoWithAudioFormat();
}
public Format getBestVideoFormat() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.bestVideoFormat();
}
public Format getBestAudioFormat() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.bestAudioFormat();
}
public List<Format> getFormatsByExtension(Extension extension) {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.findFormats(format -> format.extension() == extension);
}
public Format getFormatByItag(int itag) {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.findFormatByItag(itag);
}
public List<VideoWithAudioFormat> getAvailableFormats() {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
return currentVideo.videoWithAudioFormats();
}
public Format selectFormat(int formatIndex) {
List<VideoWithAudioFormat> formats = getAvailableFormats();
if (formatIndex < 0 || formatIndex >= formats.size()) {
return currentVideo.bestVideoWithAudioFormat();
}
return formats.get(formatIndex);
}
public File downloadVideo(Format selectedFormat, File outputDir) throws YoutubeException {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
// Verificar el formato seleccionado antes de la descarga
System.out.println("Formato seleccionado: " + selectedFormat.itag()+ " - " + selectedFormat.extension());
System.out.println("Formato seleccionado: " + selectedFormat.url());
System.out.println("Formato seleccionado: " + selectedFormat.bitrate());
System.out.println("Formato seleccionado: " + selectedFormat.mimeType());
System.out.println("Formato seleccionado: " + selectedFormat.type());
System.out.println("Formato seleccionado: " + selectedFormat.lastModified());
outputDir.mkdirs(); // Asegura que el directorio exista
RequestVideoFileDownload downloadRequest = new RequestVideoFileDownload(selectedFormat)
.saveTo(outputDir)
.renameTo(sanitizeFileName(currentVideo.details().title()))
.overwriteIfExists(true);
System.out.println("Descargando video...");
Response<File> downloadResponse = downloader.downloadVideoFile(downloadRequest);
// Verificar el archivo descargado
File downloadedFile = downloadResponse.data();
System.out.println("Archivo descargado: " + downloadedFile.getAbsolutePath());
return downloadedFile;
}
private static String sanitizeFileName(String fileName) {
return fileName.replaceAll("[\\\\/:*?\"<>|]", "_");
}
Here I insert and display the formats in a comboBox
if (outputDirectory != null && !outputDirectory.isEmpty()) { txtRutaSalida.setText(outputDirectory); // Suponiendo que tienes un campo de texto para mostrar la ruta seleccionada
// Obtener la URL del video desde el campo de texto
String videoUrl = txtUrlVideo.getText();
if (videoUrl == null || videoUrl.trim().isEmpty()) {
JOptionPane.showMessageDialog(this, "Por favor ingrese una URL de video.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
String videoId = downloader.extractVideoId(videoUrl);
if (videoId.isEmpty()) {
JOptionPane.showMessageDialog(this, "No se pudo extraer el ID del video de la URL proporcionada.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
VideoInfo videoInfo = downloader.getVideoInfo(videoId);
txtTitulo.setText(videoInfo.details().title());
DefaultComboBoxModel<FormatDTO> model = new DefaultComboBoxModel<>();
model.addElement(new FormatDTO(-1, "Seleccionar")); // Elemento predeterminado
// Agregar formatos de video con audio
List<VideoWithAudioFormat> videoWithAudioFormats = downloader.getVideoWithAudioFormats();
for (int i = 0; i < videoWithAudioFormats.size(); i++) {
VideoWithAudioFormat format = videoWithAudioFormats.get(i);
FormatDTO formatDTO = new FormatDTO(i, "Video+Audio: " + format.videoQuality() + " - " + format.extension());
model.addElement(formatDTO);
}
// Agregar formatos de video sin audio
List<VideoFormat> videoFormats = downloader.getVideoFormats();
for (int i = 0; i < videoFormats.size(); i++) {
VideoFormat format = videoFormats.get(i);
FormatDTO formatDTO = new FormatDTO(videoWithAudioFormats.size() + i, "Video: " + format.videoQuality() + " - " + format.extension());
model.addElement(formatDTO);
}
// Agregar formatos de audio
List<AudioFormat> audioFormats = downloader.getAudioFormats();
for (int i = 0; i < audioFormats.size(); i++) {
AudioFormat format = audioFormats.get(i);
FormatDTO formatDTO = new FormatDTO(videoWithAudioFormats.size() + videoFormats.size() + i, "Audio: " + format.audioQuality() + " - " + format.extension());
model.addElement(formatDTO);
}
cmbFormatos.setModel(model);
} catch (YoutubeException e) {
JOptionPane.showMessageDialog(this, "Error al obtener la información del video: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
private void btnDescargarActionPerformed(java.awt.event.ActionEvent evt) {
FormatDTO selectedFormat = (FormatDTO) cmbFormatos.getSelectedItem();
if (selectedFormat == null || selectedFormat.getIndex() == -1) {
JOptionPane.showMessageDialog(this, "Por favor seleccione un formato.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
Format format = downloader.selectFormat(selectedFormat.getIndex());
File outputDir = new File(outputDirectory);
File downloadedFile = downloader.downloadVideo(format, outputDir);
JOptionPane.showMessageDialog(this, "Video descargado exitosamente: " + downloadedFile.getAbsolutePath(), "Éxito", JOptionPane.INFORMATION_MESSAGE);
} catch (YoutubeException e) {
JOptionPane.showMessageDialog(this, "Error al descargar el video: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
I believe there is bug somewhere in your code near selectFormat(formatIndex)
:
public Format selectFormat(int formatIndex) {
List<VideoWithAudioFormat> formats = getAvailableFormats();
if (formatIndex < 0 || formatIndex >= formats.size()) {
return currentVideo.bestVideoWithAudioFormat(); <-------- it returns here
}
return formats.get(formatIndex);
}
bestVideoWithAudioFormat
- returns format with video and audio and it always has lower quality - thats how youtube returns it
If you want high quality you should select only from video formats (without audio)
I've just tested with your video and I can download both low (video+audio) and high (video only) quality.
Thanks for your comments, you helped me a lot. Now I have an error, and it is that when testing with an 8k video, and when obtaining the best video format, I find an exception: Error parsing format: unknown itag 571
code:
public static void main(String[] args) throws YoutubeException {
DownloaderVideoFinal dow = new DownloaderVideoFinal();
String id = dow.extractVideoId("https://youtu.be/QqI9eKQnFL4?si=r01eXHpPxQI0sdUI");
dow.getVideoInfo(id);
VideoFormat formato = (VideoFormat) dow.getBestVideoFormat();
File oupuString = null;
dow.downloadVideo(formato, oupuString);
}
public String extractVideoId(String urlVideo) {
System.out.println("YouTube Video Downloader");
System.out.print("URL del video de YouTube: " + urlVideo);
Pattern pattern = Pattern.compile("(?<=watch\?v=|/videos/|embed\/|youtu.be\/|\/v\/|\/e\/|watch\?v%3D|watch\?feature=player_embedded&v=|%2Fvideos%2F|embed%u200C%u200B2F|youtu.be%2F|%2Fv%2F)[^#\&\?\n]*");
Matcher matcher = pattern.matcher(urlVideo);
return matcher.find() ? matcher.group() : "";
}
public VideoInfo getVideoInfo(String videoId) throws YoutubeException {
RequestVideoInfo request = new RequestVideoInfo(videoId);
Response
private File downloadVideo(VideoFormat videoFormat, File outputDir) throws YoutubeException {
if (currentVideo == null) {
throw new IllegalStateException("Video info not loaded. Call getVideoInfo first.");
}
outputDir.mkdirs(); // Asegura que el directorio exista
String fileName = sanitizeFileName(currentVideo.details().title()) + "." + videoFormat.extension(); // Usa la extensión del formato
RequestVideoFileDownload downloadRequest = new RequestVideoFileDownload(videoFormat)
.saveTo(outputDir)
.renameTo(fileName)
.overwriteIfExists(true);
System.out.println("Descargando video...");
Response<File> downloadResponse = downloader.downloadVideoFile(downloadRequest);
// Verificar el archivo descargado
File downloadedFile = downloadResponse.data();
System.out.println("Archivo descargado: " + downloadedFile.getAbsolutePath());
return downloadedFile;
}
@MavenW added missing itags for 8k videos in 3.2.4 version, update and check
Well the thing is that for some reason the downloaded videos only appear in medium quality even if you select the highest quality format, I don't know if it is an error or if that is the behavior