Introduction
YouTube is the biggest video sharing platform in the world. It is headquartered in San Bruno, California. The service was created by three former PayPal employees-Chad Hurley, Steve Chen, and Jawed Karim – in February 2005. Google bought the site in November 2006. YouTube now operates as one of Google’s subsidiaries.
The site allows a user to upload, view, rate, share, add to favorites, report, comment on videos and subscribe to other channels. In order to upload a video or create a channel, you have to register yourself. Your Gmail account is enough to add videos and to open a channel. The only disadvantage of this site is that it does not have a download option. You cannot download videos directly from the website. Direct download is not available in order to protect the users' content. Some of the content available on YouTube is copyrighted.
Here comes the app I have developed. This app is capable of downloading videos from YouTube. What this app does is, it sends an HTTP request to the YouTube Server using the video ID. In response, the server returns video info. The video info contains the URL to download the video. But there is one problem - the URL is encoded. So first, the URL is decoded by the app and then used to download the video. But that does not mean you can download copyright content.
If you send HTTP requests to download the copyright video to the Server, you will not get video URL in response. Also, just a slight nit pick - the app is not perfect. Sometimes, it refuses to download the video however the video is available in the public domain. But guys, don’t worry; just download it again. If you download the installer, the app will download the video in the apps folder. Since the app is installed in the C drive, you should run it using administrative privileges. You can see the code below. These are well documented. I have used Net-beans as an IDE.
-
-
-
-
-
- package youtubedownloader;
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLDecoder;
- import javafx.application.Application;
- import javafx.concurrent.Service;
- import javafx.concurrent.Task;
- import javafx.concurrent.WorkerStateEvent;
- import javafx.event.ActionEvent;
- import javafx.scene.Group;
- import javafx.scene.Scene;
- import javafx.scene.control.Alert;
- import javafx.scene.control.Alert.AlertType;
- import javafx.scene.control.Button;
- import javafx.scene.control.Label;
- import javafx.scene.control.ProgressBar;
- import javafx.scene.control.TextField;
- import javafx.scene.text.Font;
- import javafx.stage.Stage;
-
-
-
-
- public class YoutubeDownloader extends Application {
-
- private Button downloadBtn = new Button();
- private TextField youtubeUrlField = new TextField();
- private TextField fileName = new TextField();
- private Label label1 = new Label();
- private Label label2 = new Label();
- private Label about = new Label("Created and Developed by Deepank Pant");
- private ProgressBar pbar = new ProgressBar(0);
- private URL downloadURL;
- @Override
- public void start(Stage primaryStage) {
-
- Font poorRichard = new Font("Poor Richard", 16);
- Font poorRichard2 = new Font("Poor Richard", 13);
-
- downloadBtn.setText("Download");
- downloadBtn.setFont(poorRichard);
- downloadBtn.setLayoutX(10);
- downloadBtn.setLayoutY(200);
- youtubeUrlField.setFont(poorRichard);
- youtubeUrlField.setLayoutX(10);
- youtubeUrlField.setLayoutY(80);
- youtubeUrlField.setPrefColumnCount(23);
- fileName.setFont(poorRichard);
- fileName.setLayoutX(10);
- fileName.setLayoutY(150);
- fileName.setPrefColumnCount(23);
- label1.setFont(poorRichard);
- label1.setText("Youtube URL");
- label1.setLayoutX(10);
- label1.setLayoutY(50);
- label2.setFont(poorRichard);
- label2.setText("File Name (Optional)");
- label2.setLayoutX(10);
- label2.setLayoutY(120);
- pbar.setVisible(false);
- pbar.setPrefWidth(350);
- pbar.setLayoutX(100);
- pbar.setLayoutY(200);
- about.setFont(poorRichard2);
- about.setLayoutX(20);
- about.setLayoutY(260);
-
- downloadBtn.setOnAction((ActionEvent event) -> {
- sendHTTPRequest.restart();
- });
-
- sendHTTPRequest.setOnSucceeded((WorkerStateEvent we) -> {
- try {
- downloadURL = new URL(getURLS(sendHTTPRequest.getValue()));
- pbar.progressProperty().unbind();
- pbar.setProgress(0);
- pbar.progressProperty().bind(VideoDownload.progressProperty());
- pbar.setVisible(true);
-
- VideoDownload.restart();
- } catch (MalformedURLException ex) {
- Alert msg = new Alert(AlertType.INFORMATION);
- msg.setTitle("Message from Youtube Downloader");
- msg.setContentText("Invalid Url");
- msg.showAndWait();
- }
- });
-
- VideoDownload.setOnSucceeded((WorkerStateEvent we) -> {
- boolean val = VideoDownload.getValue();
- System.out.println(val);
- if (val) {
- Alert msg = new Alert(AlertType.INFORMATION);
- msg.setTitle("Message from Youtube Downloader");
- msg.setContentText("Download complete");
- msg.showAndWait();
- } else {
- Alert msg = new Alert(AlertType.INFORMATION);
- msg.setTitle("Message from Youtube Downloader");
- msg.setContentText("Download Failed");
- msg.showAndWait();
- }
- pbar.setVisible(false);
- });
- Group root = new Group();
- root.getChildren().add(downloadBtn);
- root.getChildren().add(youtubeUrlField);
- root.getChildren().add(fileName);
- root.getChildren().add(label1);
- root.getChildren().add(label2);
- root.getChildren().add(pbar);
- root.getChildren().add(about);
- Scene scene = new Scene(root, 500, 280);
- primaryStage.setTitle("Youtube Downloader");
- primaryStage.setScene(scene);
- primaryStage.setResizable(false);
- primaryStage.show();
- }
-
-
-
-
- private String getVideoID(String url) {
- int index = url.indexOf("v=");
- String;
- index += 2;
- for (int i = index; i < url.length(); i++) id += url.charAt(i);
- return id;
- }
-
-
-
- final private Service < StringBuilder > sendHTTPRequest = new Service < StringBuilder > () {
- @Override
- protected Task < StringBuilder > createTask() {
- return new Task < StringBuilder > () {
- @Override
- protected StringBuilder call() {
- String response;
- StringBuilder res = new StringBuilder();
- StringBuilder refinedres = new StringBuilder();
- try {
- URL url = new URL("https://www.youtube.com/get_video_info?&video_id=" + getVideoID(youtubeUrlField.getText()));
- System.out.println(url.toString());
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- System.out.println(conn.getResponseMessage());
- BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- while ((response = in .readLine()) != null) res.append(response);
- refinedres.append(URLDecoder.decode(URLDecoder.decode(res.toString(), "UTF-8"), "UTF-8")); in .close();
- return refinedres;
- } catch (MalformedURLException ex) {} catch (IOException ex) {}
- return null;
- }
- };
- }
- };
-
- Service < Boolean > VideoDownload = new Service < Boolean > () {
- @Override
- protected Task < Boolean > createTask() {
- return new Task < Boolean > () {
- @Override
- protected Boolean call() throws Exception {
- long length;
- boolean completed = false;
- int count = 0;
- try (BufferedInputStream bis = new BufferedInputStream(downloadURL.openStream()); FileOutputStream fos = new FileOutputStream(fileName.getText().length() == 0 ? "video.mp4" : fileName.getText().concat(".mp4"))) {
- length = downloadURL.openConnection().getContentLength();
- int i = 0;
- final byte[] data = new byte[1024];
- while ((count = bis.read(data)) != -1) {
- i += count;
- fos.write(data, 0, count);
- updateProgress(i, length);
- }
- completed = true;
- } catch (IOException ex) {}
- return completed;
- }
- };
- }
- };
-
-
- private String getURLS(StringBuilder response) {
- StringBuilder temp1 = new StringBuilder();
- String[] temp2, temp3, temp4;
- try {
- int index = response.indexOf("url_encoded_fmt_stream_map");
- for (int i = index; i < response.length(); i++) {
- temp1.append(response.charAt(i));
- }
- temp2 = temp1.toString().split("&url=");
- if (temp2.length > 0) {
- temp3 = temp2[1].split(";");
- if (temp3.length > 0) {
- temp4 = temp3[0].split(",");
- if (temp4.length > 0) return temp4[0];
- else return temp3[0];
- } else return temp2[1];
- }
- } catch (Exception e) {
- Alert msg = new Alert(AlertType.INFORMATION);
- msg.setTitle("Message form youtube Downloader");
- msg.setContentText("Error in downloading");
- msg.showAndWait();
- }
- return null;
- }
-
-
-
- public static void main(String[] args) {
- launch(args);
- }
- }
Remember, I have used Java 8 to develop this app. Readers are advised to install Java 8 in order to run the code. I have also created a stand-alone installer for which you do not need the trace of Java to be installed on your system. The installer contains all the Java runtime files required to run the application.
Since I have used 64-bit Java to create the app, it might not work in 32-bit operating systems. If you can download the source code as a Netbeans project in a zip file and the standalone installer you can follow the link below.