YouTube Video Info App Banane Ka Complete Tutorial – Stylish & Red Theme
Agar aap ek YouTube Video Info App banana chahte hain jo YouTube videos ka title, description, views, likes, aur thumbnail extract kare, toh yeh tutorial aapke liye perfect hai! Hum Java aur XML use karke ek stylish red-themed app banayenge.
1. Introduction – App Ka Purpose
Yeh app users ko YouTube videos ki basic details fetch karne mein help karega. User YouTube video URL daalega, aur app YouTube Data API use karke uss video ki details show karega.
Kya Kya Sikhenge?
- ✔ XML mein UI design karna
- ✔ Java mein API calls handle karna
- ✔ Custom styling (red theme)
- ✔ Error handling
2. App Ke Features
- ✅ YouTube video details fetch karna (Title, Description, Thumbnail)
- ✅ Material Design with red theme
- ✅ Custom buttons, cards, toast messages
- ✅ User-friendly UI with progress bar
- ✅ Error handling (invalid URL, no internet)
3. Project Structure – Files aur Unka Purpose
Humari app ki structure kuch aisi hogi:
๐ res/
├── ๐ drawable/
│ ├── button_bg.xml
│ ├── button_small_bg.xml
│ ├── card_bg.xml
│ ├── edittext_bg.xml
│ ├── toast_bg.xml
│ └── toast_error_bg.xml
│
├── ๐ layout/
│ └── activity_main.xml
│
└── ๐ values/
├── colors.xml
├── strings.xml
└── styles.xml
๐ java/
└── ๐ com.example.youtubeinfo/
└── MainActivity.java
4. Step-by-Step Implementation
๐ Step 1: XML Layout (activity_main.xml)
Yeh code activity_main.xml mein lagega:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
android:fillViewport="true">
<LinearLayout
android:id="@+id/linear12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linear13"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="@drawable/card_bg"
android:orientation="vertical"
android:elevation="4dp">
<TextView
android:id="@+id/textview10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="YouTube Info Pro"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#FF0000" />
<EditText
android:id="@+id/urlEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:padding="12dp"
android:background="@drawable/edittext_bg"
android:textSize="12sp"
android:textColor="#000000"
android:hint="Paste YouTube URL here"
android:textColorHint="#607D8B"
android:inputType="textUri" />
<Button
android:id="@+id/fetchButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/button_bg"
android:text="Fetch Video Info"
android:textSize="12sp"
android:textColor="#FFFFFF"
android:textAllCaps="false" />
</LinearLayout>
<LinearLayout
android:id="@+id/infoCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:padding="16dp"
android:background="@drawable/card_bg"
android:orientation="vertical"
android:elevation="4dp"
android:visibility="gone">
<TextView
android:id="@+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="#000000" />
<LinearLayout
android:id="@+id/linear14"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<Button
android:id="@+id/copyTitleButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/button_small_bg"
android:text="Copy Title"
android:textSize="12sp"
android:textColor="#FFFFFF"
android:layout_weight="1"
android:textAllCaps="false" />
<Button
android:id="@+id/downloadThumbnailButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:background="@drawable/button_small_bg"
android:text="Save Thumbnail"
android:textSize="12sp"
android:textColor="#FFFFFF"
android:layout_weight="1"
android:textAllCaps="false" />
</LinearLayout>
<TextView
android:id="@+id/authorTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textSize="12sp"
android:textColor="#000000" />
<ImageView
android:id="@+id/thumbnailImageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="16dp"
android:src="@drawable/default_image"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/textview11"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Description"
android:textSize="12sp"
android:textStyle="bold"
android:textColor="#FF0000" />
<TextView
android:id="@+id/descriptionTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textSize="12sp"
android:textColor="#000000" />
<Button
android:id="@+id/copyDescriptionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/button_small_bg"
android:text="⧉ Copy "
android:textSize="10sp"
android:textColor="#FFFFFF"
android:layout_gravity="end"
android:textAllCaps="false" />
<TextView
android:id="@+id/textview12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Tags"
android:textSize="12sp"
android:textStyle="bold"
android:textColor="#FF0000" />
<TextView
android:id="@+id/tagsTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textSize="12sp"
android:textColor="#000000" />
<Button
android:id="@+id/copyTagsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@drawable/button_small_bg"
android:text="⧉ Copy"
android:textSize="12sp"
android:textColor="#FFFFFF"
android:layout_gravity="end"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>
</ScrollView>
๐ Step 2: Custom Backgrounds (XML Drawables)
✔ button_bg.xml (Red Rounded Button)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF0000" />
<corners android:radius="4dp" />
</shape>
✔ card_bg.xml (White Card with Shadow)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />
<stroke
android:width="1dp"
android:color="#E0E0E0" />
</shape>
✔ button_small_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF3333" />
<corners android:radius="4dp" />
</shape>
✔ edittext_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="4dp" />
<stroke
android:width="1dp"
android:color="#B0B0B0" />
</shape>
✔ toast_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF3333" />
<corners android:radius="20dp" />
<stroke
android:width="1dp"
android:color="#CC0000" />
</shape>
✔ toast_error_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#990000" />
<corners android:radius="20dp" />
<stroke
android:width="1dp"
android:color="#660000" />
</shape>
๐ Step 3: MainActivity.java (API Call Logic)
Yeh code MainActivity.java mein lagega:
package com.my.newprojecvi;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends Activity {
private EditText urlEditText;
private Button fetchButton;
private LinearLayout infoCard;
private TextView titleTextView;
private Button copyTitleButton;
private TextView authorTextView;
private ImageView thumbnailImageView;
private Button downloadThumbnailButton;
private TextView descriptionTextView;
private Button copyDescriptionButton;
private TextView tagsTextView;
private Button copyTagsButton;
private String title;
private String author;
private String thumbnailUrl;
private String description;
private String tags;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize views
urlEditText = (EditText) findViewById(R.id.urlEditText);
fetchButton = (Button) findViewById(R.id.fetchButton);
infoCard = (LinearLayout) findViewById(R.id.infoCard);
titleTextView = (TextView) findViewById(R.id.titleTextView);
copyTitleButton = (Button) findViewById(R.id.copyTitleButton);
authorTextView = (TextView) findViewById(R.id.authorTextView);
thumbnailImageView = (ImageView) findViewById(R.id.thumbnailImageView);
downloadThumbnailButton = (Button) findViewById(R.id.downloadThumbnailButton);
descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
copyDescriptionButton = (Button) findViewById(R.id.copyDescriptionButton);
tagsTextView = (TextView) findViewById(R.id.tagsTextView);
copyTagsButton = (Button) findViewById(R.id.copyTagsButton);
fetchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String youtubeUrl = urlEditText.getText().toString().trim();
if (TextUtils.isEmpty(youtubeUrl)) {
showErrorToast("Please enter a YouTube URL");
return;
}
new FetchYouTubeInfoTask().execute(youtubeUrl);
}
});
copyTitleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyToClipboard(title, "Video title copied to clipboard");
}
});
downloadThumbnailButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (thumbnailUrl != null) {
new DownloadThumbnailTask().execute(thumbnailUrl);
}
}
});
copyDescriptionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyToClipboard(description, "Description copied to clipboard");
}
});
copyTagsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyToClipboard(tags, "Tags copied to clipboard");
}
});
}
private void copyToClipboard(String text, String successMessage) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("YouTube Info", text);
clipboard.setPrimaryClip(clip);
showSuccessToast(successMessage);
}
private void showSuccessToast(String message) {
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) findViewById(R.id.custom_toast_layout));
TextView text = (TextView) layout.findViewById(R.id.custom_toast_message);
text.setText(message);
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 100);
toast.setDuration(Toast.LENGTH_SHORT);
toast.setView(layout);
toast.show();
}
private void showErrorToast(String message) {
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) findViewById(R.id.custom_toast_layout));
TextView text = (TextView) layout.findViewById(R.id.custom_toast_message);
text.setText(message);
// Change background color for errors
LinearLayout toastLayout = (LinearLayout) layout.findViewById(R.id.custom_toast_layout);
toastLayout.setBackgroundResource(R.drawable.toast_error_bg);
Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 100);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}
private String extractVideoId(String youtubeUrl) {
String videoId = null;
Pattern pattern = Pattern.compile(
"^https?://.*(?:youtu.be/|v/|u/\\w/|embed/|watch\\?v=)([^#&?]*).*$",
Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(youtubeUrl);
if (matcher.matches()) {
videoId = matcher.group(1);
}
return videoId;
}
private class FetchYouTubeInfoTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String youtubeUrl = params[0];
String videoId = extractVideoId(youtubeUrl);
if (videoId == null) {
return "INVALID_URL";
}
// First get basic info from oEmbed
String oEmbedUrl = "https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=" + videoId + "&format=json";
try {
// Step 1: Get basic info from oEmbed
URL url = new URL(oEmbedUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
StringBuilder response = new StringBuilder();
int data;
while ((data = reader.read()) != -1) {
response.append((char) data);
}
reader.close();
JSONObject jsonResponse = new JSONObject(response.toString());
title = jsonResponse.getString("title");
author = jsonResponse.getString("author_name");
thumbnailUrl = jsonResponse.getString("thumbnail_url");
// Step 2: Get full page to extract description and tags
String videoPageUrl = "https://www.youtube.com/watch?v=" + videoId;
String pageContent = getUrlContent(videoPageUrl);
// Extract description
description = extractDescription(pageContent);
if (description == null) description = "Description not available";
// Extract tags
tags = extractTags(pageContent);
if (tags == null) tags = "Tags not available";
return "SUCCESS";
} else {
return "HTTP_ERROR: " + responseCode;
}
} catch (Exception e) {
return "ERROR: " + e.getMessage();
}
}
private String getUrlContent(String urlString) throws Exception {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
StringBuilder response = new StringBuilder();
int data;
while ((data = reader.read()) != -1) {
response.append((char) data);
}
reader.close();
return response.toString();
}
private String extractDescription(String pageContent) {
try {
Pattern pattern = Pattern.compile("\"description\":\\{\"simpleText\":\"([^\"]*)\"");
Matcher matcher = pattern.matcher(pageContent);
if (matcher.find()) {
return matcher.group(1).replace("\\n", "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String extractTags(String pageContent) {
try {
Pattern pattern = Pattern.compile("\"keywords\":\\[(.*?)\\]");
Matcher matcher = pattern.matcher(pageContent);
if (matcher.find()) {
String tagsJson = matcher.group(1);
return tagsJson.replace("\"", "").replace(",", ", ");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
if (result.equals("SUCCESS")) {
infoCard.setVisibility(View.VISIBLE);
titleTextView.setText(title);
authorTextView.setText("By: " + author);
descriptionTextView.setText(description);
tagsTextView.setText(tags);
new LoadThumbnailTask().execute(thumbnailUrl);
} else {
infoCard.setVisibility(View.GONE);
showErrorToast("Failed to fetch video info: " + result);
}
}
}
private class LoadThumbnailTask extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... params) {
String thumbnailUrl = params[0];
try {
URL url = new URL(thumbnailUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
thumbnailImageView.setImageBitmap(result);
} else {
showErrorToast("Failed to load thumbnail");
}
}
}
private class DownloadThumbnailTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
String thumbnailUrl = params[0];
try {
URL url = new URL(thumbnailUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
File directory = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "YouTube Thumbnails");
if (!directory.exists()) {
directory.mkdirs();
}
String fileName = "thumbnail_" + System.currentTimeMillis() + ".jpg";
File file = new File(directory, fileName);
InputStream input = new BufferedInputStream(connection.getInputStream());
FileOutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
output.close();
input.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean success) {
if (success) {
showSuccessToast("Thumbnail saved to Pictures/YouTube Thumbnails");
} else {
showErrorToast("Failed to save thumbnail");
}
}
}
}
Yeh tha complete tutorial YouTube Video Info App banane ka. Agar aapko koi doubt hai toh comments mein zaroor puchiye!
Happy Coding!
1 เคिเคช्เคชเคฃिเคฏाँ
Ghat Gpt ca kaca aca app banana ka lea prompt deuomga
เคเคตाเคฌ เคฆेंเคนเคाเคं