주니어개발자_ฅʕ•̫͡•ʔฅ

Android Youtube api 검색 및 재생, 영상 끝났을때 자동종료 (안드로이드 유튜브 api, JAVA) 본문

AndroidStudio

Android Youtube api 검색 및 재생, 영상 끝났을때 자동종료 (안드로이드 유튜브 api, JAVA)

뚜비뚜밥_98 2021. 5. 28. 10:20

오늘은 안드로이드에서 youtube 영상을 검색하여

제일 상위 항목의 정보를 가져와

재생시키는 부분을 구현해 보려한다.

 

먼저 영상 재생시키는 부분 참고한 사이트 정보

https://m.blog.naver.com/iampsi/221861973872

 

검색부분 구현하면서 참고한 사이트 정보

https://stickode.com/detail.html?no=2072 

목록을 보여줄 목적이 아니기 때문에

저 두 곳에서는 메인 액티비티만 참고했다.

 

그래서 구현이 간단했지만 선언해 주는 것에서 잘 못 선언해줘서

실행이 안돼 찾는데 오래걸렸다;;

(헛굴 파서 시간 엄청 버림)

 

Youtube api는 받았다고 가정하에 정리하려고 한다.

맞다 나는 api설정에서

밑에 사진에 체크된 부분을 설정하고 저장하였는데

어찌된 영문인지 실행이 되지 않아

그냥 없음에 체크하는 것으로 바꿔줬다..

어차피 나만 쓰는 것이니깐..

이렇게!

 

이제 정말 유튜브 api를 이용하여 검색하여 영상을 재생시켜 보겠다.

먼저 영상을 재생하기 위해선 영상 고유의 비디오 ID를 알아야 한다.

해당 영상 url에서 비디오 아이디는 = eAXxTUuDg04

여기서 문제는 영상마다 고유 아이디가 다를텐데 어떻게 검색으로 알아낼 것인가..?

일단 나는 무작정 위에서 참고한 사이트에서 액티비티를 복붙했고

내가 필요한 입맛대로 필요한 부분만 사용했다.

 

그 결과 유튜브 내에서 검색을 위한 소스코드는

밑에와 같다.

 

그리고 이것을 호출하여 사용할땐

사용할 메소드에

해당클래스이름.searchTask searchTask = new 해당클래스이름.searchTask();
searchTask.execute();

위와같이 작성하여 호출했다.

(ex. 클래스 이름 TestActivity라고 한다면)

TestActivity.searchTask searchTask = new TestActivity.searchTask();
searchTask.execute();

이렇게..

(전체 소스코드는 맨 밑에 첨부)

(글을 복사해서 프로젝트에 넣어 보세요. 여기서 보니 다 붙어있어서 보기 싫게 보이는군요..)

private class searchTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
        @Override
        protected Void doInBackground(Void... params) {
            try {
                JSONObject jsonObject = getUtube();
                paringJsonData(jsonObject);
            } catch (JSONException | IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {

        }
    }

    //유튜브 url에 접근하여 검색한 결과들을 json 객체로 만들어준다
    public JSONObject getUtube() throws IOException {

//intentSearch는 나는 다른 액티비티에서 이 곳으로 검색할 텍스트를 넘겨주기에 전역변수로 설정하여
// onCreate에서 intentSearch에 단어 넣어줌
//intentSearch = 검색할 단어
//API_KEY = 여러분의 youtube api 키 값
// originUrl 이것도 그냥 전역변수(String형) 설정함

        originUrl = "https://www.googleapis.com/youtube/v3/search?"
                + "part=snippet&q=" + intentSearch
                + "&key="+ API_KEY+"&maxResults=3"; 
                //&maxResults=3 여기는 몇개의 항목을 나타낼 것 인지임
                //나는 상위 한개의 항목만 필요하지만 그냥 3개 했음
                //최대 50개의 항목까지 쓸 수 있는걸로 알고 있음

        URL url = new URL(originUrl);

        HttpURLConnection connection =(HttpURLConnection)url.openConnection();
        connection.setRequestMethod("GET");
        connection.setReadTimeout(10000);
        connection.setConnectTimeout(15000);
        connection.connect();

        String line;
        String result="";
        InputStream inputStream=connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer response = new StringBuffer();

        while ((line = reader.readLine())!=null){
            response.append(line);
        }
        result=response.toString();

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = new JSONObject(result);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return jsonObject;
    }

    //json 객체를 가지고 와서 필요한 데이터를 파싱한다.
    //파싱을 하면 여러가지 값을 얻을 수 있는데 필요한 값들을 세팅하여 사용
    
    private void paringJsonData(JSONObject jsonObject) throws JSONException {

        JSONArray contacts = jsonObject.getJSONArray("items");

    //앞서 말했다 싶이 나는 상위 1개 영상만을 재생할 것이기에
    //반복문을 사용하지 않고 바로 인덱스 0번 정보를 가져왔다
        JSONObject c = contacts.getJSONObject(0);
        String kind =  c.getJSONObject("id").getString("kind"); // 종류를 체크하여 playlist도 저장
        if(kind.equals("youtube#video")){
            vodid = c.getJSONObject("id").getString("videoId"); // 유튜브
        }else{
            vodid = c.getJSONObject("id").getString("playlistId"); // 유튜브
        }
        videoID = vodid; 
        //사실상 videoID와 vodid는 같은 String형이라 그냥 vodid 갖다써도 되는데
        // 왜 이렇게 했는지;;
        Log.i("비디오", vodid);
    }

만약 위의 소스코드를 실행하는데 빨간줄이 나타난다면

Gradle(app)을 보자

 

프로젝트를 구현하면서 어떤 부분을 추가한지는

모르겠지만 dependencies 부분에

implementation 'com.google.apis:google-api-services-youtube:v3-rev183-1.22.0'
implementation 'com.google.http-client:google-http-client-android:+'
implementation 'com.google.api-client:google-api-client-android:+'
implementation 'com.google.api-client:google-api-client-gson:+'


implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation files('libs/YoutubeAndroidPlayerApi.jar')

implementation files('libs/google_http_client_jackson2-1.0.0.jar')

 

이렇게 추가했다.

 

맨 밑에 두줄은 jar를 각각 다운받아 모듈에 추가해 줌

(클릭시 다운받는 곳과 적용하는 방법 알 수 있음)

메인액티비티

import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private Button btn1, btn2, btn3;

    private String str;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn1 = (Button)findViewById(R.id.oneBtn);
        EditText et = (EditText)findViewById(R.id.testEdit);

        btn1.setOnClickListener(view ->{
            str = et.getText().toString(); //검색할 항목 적을 EditText칸
            if(!str.equals(""))
            	activityIntent(str);
            else 
            	Toast.makeText(getApplicationContext(),"입력해주세요",Toast.LENGTH_SHORT).show();
        });
    }

    public void activityIntent(String str){
        Intent intent = new Intent(getApplicationContext(),WebViewYoutube.class);
        intent.putExtra("name",str);
        startActivity(intent);
    }

}

 

검색 후 영상 재생 코드는 좀 복잡하다.

해당 액티비티로 넘어왔을때

이전 액티비티에서 검색할 텍스트를 넘겨받고

영상을 틀것인지 다이어그램으로 물어보며

영상을 본다고 하면 영상이 재생된다.

그리고 영상이 끝나면 알아서 액티비티 종료

 

넘겨받은 텍스트에 대한 영상 검색 및 영상 재생 액티비티 전체

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;


import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

public class WebViewYoutube extends YouTubeBaseActivity {

    private YouTubePlayerView youTubePlayerView;
    private YouTubePlayer player;
    private String originUrl, vodid = "";
    private String intentSearch;

    final String API_KEY="이곳에 여러분의 youtube api 키를 넣어주세요";
    private String videoID = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview);

        Intent intent = getIntent();
        
        //전 액티비티에서 intent로 name이라는 이름으로 검색할 텍스트를 보냄
        //전 액티비티에서 다른 액티비티로 변수 넘겨줄때
        //intent.putExtra("넘겨줄 변수명","넘겨줄 변수값");
        //intent.putExtra("name","아무거나");
        //startActivity(intent);부분의 위에 작성한다.
        
        intentSearch = intent.getExtras().getString("name");//변수 넘겨받을때(변수 이름이 name이라고 생각하면 좀 더 쉽다.)
        initPlayer(); //비디오 로딩 및 여러가지 준비

		// 검색 Task 실행하여 비디오 아이디 추출 시작
        WebViewYoutube.searchTask searchTask = new WebViewYoutube.searchTask();
        searchTask.execute();

        AlertDialog.Builder aDialog = new AlertDialog.Builder(this);
        aDialog.setTitle("안내");
        aDialog.setMessage( intentSearch+" 영상을 시청하시겠습니까?");

        aDialog.setPositiveButton("네", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                playVideo(); //사실상 "네"버튼은 비디오 재생 버튼 역할,,,
                dialog.dismiss();
            }
        }).setCancelable(false);

        aDialog.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish(); //액티비티 종료, 이전 액티비티로 돌아감
            }
        });

        AlertDialog ad = aDialog.create();
        ad.show();
    }
    
    public void initPlayer() {
        youTubePlayerView = findViewById(R.id.playerView);
        // YouTubePlayerView 초기화하기
        youTubePlayerView.initialize(API_KEY, new YouTubePlayer.OnInitializedListener() {
            @Override
            public void onInitializationSuccess(YouTubePlayer.Provider provider,
                                                YouTubePlayer youTubePlayer, boolean b) {
                player = youTubePlayer;
                player.setPlayerStateChangeListener(new YouTubePlayer.PlayerStateChangeListener() {
                    @Override
                    public void onLoading() {}

                    @Override
                    public void onLoaded(String s) {
                        Log.e("PlayerView", "onLoaded 호출됨: " + s);
                        player.play(); // 동영상이 로딩되었으면 재생하기
                    }

                    @Override
                    public void onAdStarted() {}

                    @Override
                    public void onVideoStarted() {}

                    @Override
                    public void onVideoEnded() {
                        finish(); //영상이 끝났다면 액티비티 종료, 이전 액티비티로 돌아감
                    }

                    @Override
                    public void onError(YouTubePlayer.ErrorReason errorReason) {}
                });
            }

            @Override
            public void onInitializationFailure(YouTubePlayer.Provider provider,
                                                YouTubeInitializationResult youTubeInitializationResult) {}
        });
    } // initPlayer

    public void playVideo() {
        if (player != null) {
            player.cueVideo(videoID); //비디오 재생
        }
    }

//==============여기서부터는 검색을 위한 메소드들==========================
    private class searchTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                JSONObject jsonObject = getUtube();
                paringJsonData(jsonObject);
            } catch (JSONException | IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {

        }
    }

    //유튜브 url에 접근하여 검색한 결과들을 json 객체로 만들어준다
    public JSONObject getUtube() throws IOException {

        originUrl = "https://www.googleapis.com/youtube/v3/search?"
                + "part=snippet&q=" + intentSearch
                + "&key="+ API_KEY+"&maxResults=3";

        URL url = new URL(originUrl);

        HttpURLConnection connection =(HttpURLConnection)url.openConnection();
        connection.setRequestMethod("GET");
        connection.setReadTimeout(10000);
        connection.setConnectTimeout(15000);
        connection.connect();

        String line;
        String result="";
        InputStream inputStream=connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer response = new StringBuffer();

        while ((line = reader.readLine())!=null){
            response.append(line);
        }
        result=response.toString();

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = new JSONObject(result);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return jsonObject;
    }

    //json 객체를 가지고 와서 필요한 데이터를 파싱한다.
    //파싱을 하면 여러가지 값을 얻을 수 있는데 필요한 값들을 세팅하여 사용
    private void paringJsonData(JSONObject jsonObject) throws JSONException {

        JSONArray contacts = jsonObject.getJSONArray("items");

        JSONObject c = contacts.getJSONObject(0);
        String kind =  c.getJSONObject("id").getString("kind"); // 종류를 체크하여 playlist도 저장
        if(kind.equals("youtube#video")){
            vodid = c.getJSONObject("id").getString("videoId"); // 유튜브
        }else{
            vodid = c.getJSONObject("id").getString("playlistId"); // 유튜브
        }
        videoID = vodid;
        Log.i("비디오", vodid);
    }

}


 

메인액티비티 레이아웃(R.layout.activity_main)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/testEdit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/oneBtn"/>

    <Button
        android:id="@+id/oneBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="검색"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

 

영상보여줄 액티비티 레이아웃(R.layout.webview)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">


        <com.google.android.youtube.player.YouTubePlayerView
            android:id="@+id/playerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

</RelativeLayout>