webSQL이라는 것은 Web 버전의 데이터 베이스라고 이해하면 된다.


 서버에서 사용되는 데이터 베이스가 아닌 해당 브라우져의 데이터 베이스이기 때문에 쿠키랑은 차별된 정보가 존재한다.


 단점은 각 브라우져에게 데이터 베이스가 공유되지 않는 단점이 있다.(확인 결과 익스플로러는 최신 버전에서도 될 수 있을지 생각해봐야 될것이다.


 전체 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<!DOCTYPE html>
<html>
  <body>
    <div id="player" style="position:fixed; bottom:10px; z-index:10; right:10px;"></div>
    <script>
      var db;
      
      var url;
      
      var tag = document.createElement("script");
 
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName("script")[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      
      db = window.openDatabase("myDB","1.0""테스트용DB"1024*1024);
      
      db.transaction
      (
        function(tx)
        {
            tx.executeSql("create table YoutubeListData(video,currentTime)");
        }
      );
      
      var player;
      
      function onYouTubeIframeAPIReady() {
        player = new YT.Player("player", {
          height: "400",
          width: "600",
          playerVars: { "autoplay"0"controls"1 },
          events: {
            "onReady": onPlayerReady,
            "onStateChange": onPlayerStateChange,
            "onError": onPlayerError,
          }
        });
      }
      
      function onPlayerReady(event) {
            player.cuePlaylist({
                        list:"UUI0Ai1RoRD-b8i-qvRR0Yeg",
                        listType:"playlist",
                        index:"0",
                        suggestedQuality:"default"
                    });
      }
      
      function onPlayerError(event) {
        console.log("Error"+event);
      }
 
      var done = false;
      var play = false;
      var name = 0;
      var currentTimer = null;
      
      function onPlayerStateChange(event) {
        
        switch(event.data)
        {
            case -1:
            case 2:
            case 3:
                clearInterval(currentTimer);
                break;
            case 0:
                break;
            case 1:
                url = player.getVideoUrl();
                url = url.substring(url.indexOf("v=")+2,url.length);
                db.transaction
                (
                    function(tx)
                    {
                        tx.executeSql("update YoutubeListData set video=? where rowid=1",[url]);
                    }
                );
                currentTimer = setInterval(consoleCurrentTime,500);
                break;
            case 5:
                url = player.getVideoUrl();
                url = url.substring(url.indexOf("v=")+2,url.length);
                
                db.transaction
                (
                    function(tx)
                    {
                        tx.executeSql("SELECT * FROM YoutubeListData", [], function (tx, results) {
                            var len = results.rows.length;
                            if(len == 0)
                            {
                                tx.executeSql("INSERT INTO YoutubeListData (video,currentTime) VALUES ('"+url+"', 0)");
                            }
                            else
                            {
                                var index = player.getPlaylist().indexOf(results.rows.item(0).video);
                                player.playVideoAt(index);
                                player.seekTo(results.rows.item(0).currentTime);
                            }
                        }, null);
                    }
                );
                
                player.playVideo();
                break;
        }
      }
      
      function nextVideo(){
        player.addEventListener("onStateChange",onPlayerStateChange);
        player.nextVideo();
      }
      
      function consoleCurrentTime(){
        db.transaction
        (
            function(tx)
            {
                tx.executeSql("update YoutubeListData set currentTime=? where rowid=1",[player.getCurrentTime()]);
            }
        );
      }
      
    </script>
  </body>
</html>
 
cs


 과거에 Youtube Player을 연결한 것은 블로그가 iframe을 하지 않는 이상은 제대로 동작을 하지 못하는 단점이 있었다.(그래서 처음 부터 동영상을 봐야되는 단점이 있음.)


 이것을 webSQL을 이용해서 처리한 것이다.(어짜피 Youtube Player Javascript API는 크롬 및 기타 브라우져에서만 제대로 동작한다.)


 동작되는 예시는 현재 적용한 블로그의 형태를 보면 이해가 될 것이다.



Posted by JunkMam
,

 SCM Music Player가 들어가 있는 블로그를 보면서 특정 영상을 가지고와서 공유하는 장치를 만들면 어떨까? 라는 생각을 하게 되서 한번 테스트해서 만들어 본것이다.


 HTML 소스는 다음과 같다.

1
2
3
<div style="position:fixed; bottom:10px; z-index:10; left:10px;">
    <embed height=300 width=400 src="https://www.youtube.com/embed/?list=UUI0Ai1RoRD-b8i-qvRR0Yeg" style="z-index:10;">
</div>
cs



 이걸 HTML/CSS 형태로 다시  맞춘다면,


 HTML 소스


1
2
3
<div class="top">
    <embed src="https://www.youtube.com/embed/?list=UUI0Ai1RoRD-b8i-qvRR0Yeg" class="top video">
</div>
cs


 CSS 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.top
{
    position:fixed;
    bottom:10px;
    left:10px;
    z-index:10;
}
.top .video
{
    height:300;
    width:400 
}
 
cs


 이렇게 사용하면, 밑에 동영상이 나오게 된다.


 참고로 Youtube에서 공유 형식으로 가지고 올려면, 다음과 같은 경로를 잡아줘야한다.


 https://www.youtube.com/embed/재생하고자 하는 영상 ID


 list로 전부 다 하고자 한다면, 다음과 같이 한다.


 https://www.youtube.com/embed/?list=재생 리스트 ID


 이렇게 사용한다면, 재생 리스트로 출력하게 된다.



 장점은 IE랑 기타 브라우져에서 전부 다 적용이 가능하다.


 하지만, 문제점이 있다.


 embed는 변수로 뽑아 낼 수가 없다.(iframe 또한 동일하다.)


 쉽게 말해서 저기서 다음과 같은 형태의 변수를 만들어 낸다고 해보자.


1
2
var embl = document.getElementsByTagName("embed");
 
cs


 윗 소스의 결과 embl는 null(존재하지 않음)이라는 형태로 나오게된다.


 null(존재 하지 않음)이기 때문에 제대로 작동이 안되고, 결국은 오류가 나게 된다.


 다음은 구글링해서 얻은 정보이다.


 구글에서 제공하는 JavaScript로 컨트롤 할 수 있는 API가 존재한다.


 이걸 이용해서 일부분만 듣게 하고 사용자가 플레이를 틀어서 다시 듣게 만들 수 있다.

 쉽게 말해서 플레이어를 컨트롤 할 수 있게 된다는 것이다.


 Youtube 개발자 사이트[각주:1]에서 자세한 설명이 나온다.


 자세히 알려면, 다음을 알아야 된다.


 https://www.youtube.com/iframe_api


 여기서 iframe_api란 무엇인가?

 이것은 바로 위에 언습한, https://www.youtube.com/embed/를 iframe으로 처리해주는 장치들이 들어가 있는 주소이다.(들어가보면, javascript들이 나온다.)


 Youtube 개발자 사이트에서는 다음과 같은 예제를 제공해준다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>
 
    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');
 
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
 
      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '390',
          width: '640',
          videoId: 'I1-YOOLU_qY',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }
 
      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }
 
      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>
cs


 이걸 본다면, 이벤트가 포함이 되어서 6초 후에 멈추는걸 볼 수 있다.


 이걸 이용해서 컨트롤을 할 수 있다.

 단, 이 경우에는 단일 영상에서만 가능하다.

 우리는 리스트를 원한다. 라고한다면, 다음과 같은 형태를 사용하면, 리스트를 부를 수 있게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<!DOCTYPE html>
<html>
  <body>
    <div id="player" style="position:fixed; bottom:10px; z-index:10; left:10px;"></div>
    <script>
    
      var tag = document.createElement('script');
 
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
      
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '300',
          width: '300',
          videoId: 'kjjZtbYEhCQ',
          playerVars: { 'autoplay'1'controls'0 },
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange,
            'onError': onPlayerError,
          }
        });
      }
 
      
      function onPlayerReady(event) {
            console.log("Test");
            player.cuePlaylist({
                        list:'UUI0Ai1RoRD-b8i-qvRR0Yeg',
                        listType:'playlist',
                        index:'0',
                        suggestedQuality:'default'
                    });
      }
      
      function onPlayerError(event) {
        console.log("Error"+event);
      }
 
      var done = false;
      var play = false;
      var name = 0;
      function onPlayerStateChange(event) {
        console.log("StateChange"+event.data);
        
        switch(event.data)
        {
            case -1:
                break;
            case 0:
                name++;
                if(name==2 && play)
                {
                    play=false;
                    player.removeEventListener('onStateChange',onPlayerStateChange);
                    setTimeout(nextVideo, 1000);
                }
                break;
            case 1:
                if(!done)
                {
                    setTimeout(stopVideo, 6000);
                    done=true;
                }
                play=true;
                break;
            case 5:
                player.playVideo();
                break;
        }
      }
      
      function nextVideo(){
        player.addEventListener('onStateChange',onPlayerStateChange);
        player.nextVideo();
      }
      
      function stopVideo() {
        player.pauseVideo();
      }
      
    </script>
  </body>
</html>
cs


 이렇게 하면, 제대로 작동이 된다.

 여기서, removeEventListener와 addEventListener을 사용하는 이유는 중복을 막기 위해서 사용하였다.

 play와 name등으로 딜레이를 사용하셔 중복을 막는 것이다.


 블로그에서 youtube에 설정을 할 수 있게 되며, 

 onStateChange라는 이벤트를 이용해서 사용하는 것이다.


 Youtube로 사용한 것은 설레임 에디션을 가지고 사용하였다.


 tistory.com 등에 제대로 들어 갈려면 쿠키 작업을 해서 시간+영상 인덱스을 가지는걸로 만들어야 될 것이다.

 seek;플레이어 재생시간과 startTime;플레이어 시작시간 설정, index; 플레이 하는 위치 등이 지원되어 있기 때문에 쿠키를 사용하면 간단하게 해결될 것 같다.


 영상 리스트를 원하는 사람으로 설정할 수 있다.


 동영상 주소는 설레임 에디션 동영상이다.


 채널 주소 : https://www.youtube.com/channel/UCI0Ai1RoRD-b8i-qvRR0Yeg

  1. 검색 시간 : (2016-06-03) [본문으로]
Posted by JunkMam
,

 예제 소스가 있긴 하지만, 예제 소스를 잘 못 찾았다.(보는 법도 몰랐다.) 그래서 외국 서버를 찾았다.


 이걸 그대로 복사 붙이기 하면, 플레이어에 연결이 된다.[각주:1]


 Android 프로젝트에서 AndroidManifast.xml에 추가 시켜줘야하는게 있다.


 필자는 다음과 같이 설정했다.


 

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.sung.android" >
    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme" >
        <activity android:name=".Main_Activity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>
cs


 이렇게 처리하였다.


 여기서 중요한 것은 인터넷 통신을 위해서 권한을 하나 받아야된다.


 

1
    <uses-permission android:name="android.permission.INTERNET" />
cs



 이것을 설정한 다음, Youtube API 라이브러리에서 제공하는 플레이어 XML을 추가한다.


1
2
3
4
5
6
    <com.google.android.youtube.player.YouTubePlayerView
        android:id="@+id/youtube_player"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fff"
        android:padding="5dp" />
cs


 이 다음에 소스를 짜면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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.YouTubePlayer.ErrorReason;
import com.google.android.youtube.player.YouTubePlayer.PlaybackEventListener;
import com.google.android.youtube.player.YouTubePlayer.PlayerStateChangeListener;
import com.google.android.youtube.player.YouTubePlayer.Provider;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubePlayerView;
public class Main_Activity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
    public static final String API_KEY = "";//사용자가 얻은 API Key을 입력하면 된다.(개발자 콘솔에 얻은 것.)
    
    //http://youtu.be/<VIDEO_ID>
    public static final String VIDEO_ID = "";
    private static final int RQS_ErrorDialog = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /** attaching layout xml **/
        setContentView(R.layout.activity_main_);
        /** Initializing YouTube player view **/
        YouTubePlayerView youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtube_player);
        youTubePlayerView.initialize(API_KEY, this);
    }
    @Override
    public void onInitializationFailure(Provider provider, YouTubeInitializationResult result) {
        if (result.isUserRecoverableError()) {
            result.getErrorDialog(this, RQS_ErrorDialog).show();
        } else {
            Toast.makeText(this,
                    "YouTubePlayer.onInitializationFailure(): " + result.toString(),
                    Toast.LENGTH_LONG).show();
        }
    }
    @Override
    public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) {
        /** add listeners to YouTubePlayer instance **/
        player.setPlayerStateChangeListener(playerStateChangeListener);
        player.setPlaybackEventListener(playbackEventListener);
        /** Start buffering **/
        if (!wasRestored) {
            player.cueVideo(VIDEO_ID);
        }
    }
    private PlaybackEventListener playbackEventListener = new PlaybackEventListener() {
        @Override
        public void onBuffering(boolean arg0) {
        }
        @Override
        public void onPaused() {
        }
        @Override
        public void onPlaying() {
        }
        @Override
        public void onSeekTo(int arg0) {
        }
        @Override
        public void onStopped() {
        }
    };
    private PlayerStateChangeListener playerStateChangeListener = new PlayerStateChangeListener() {
        @Override
        public void onAdStarted() {
        }
        @Override
        public void onError(ErrorReason arg0) {
        }
        @Override
        public void onLoaded(String arg0) {
        }
        @Override
        public void onLoading() {
        }
        @Override
        public void onVideoEnded() {
        }
        @Override
        public void onVideoStarted() {
        }
    };
}
cs


 여기서 Android 버전에 따라서 바뀐 것인지 모르겠지만, 초기화 작업에서 오류가 뜨는 걸 확인 되었다.

 그래서, 다음과 같은 소스가 적용 된 것이다.

1
2
3
4
5
6
7
8
9
10
    @Override
    public void onInitializationFailure(Provider provider, YouTubeInitializationResult result) {
        if (result.isUserRecoverableError()) {
            result.getErrorDialog(this, RQS_ErrorDialog).show();
        } else {
            Toast.makeText(this,
                    "YouTubePlayer.onInitializationFailure(): " + result.toString(),
                    Toast.LENGTH_LONG).show();
        }
    }
cs


 제공한 사이트와 다른 점은 이것인데, 초기화 작업이 잘못 되었을 경우.

 원래, Youtube에 들어가서 작업 할 수 있도록 제작한 것이다.


 전체 구조에선


 onInitializationFailure()는 초기화 하는 도중에 오류가나서 초기화가 제대로 안될 경우이다. 이 경우는 Key가 문제가 있거나, 플레이어로 접속이 안되는 문제등 다양한 문제가 있을 경우 작동한다.


 onInitializationSuccess()는 초기화가 성공하면 작동되는 것이다. 여기서 player등의 초기화 작업등을 하는 것이다.

 즉, YouTube의 연결에서 사용되는 장치들을 연결 및 설정하는 것이다.


 여기서 Player의 이벤트를 연결해서 처리하는 Listener을 연결되게 된다.

Posted by JunkMam
,



 Android Youtube API을 사용하기 위해선 구글에서 제공하는 서비스를 이용해야된다.


 서비스를 이용하기 위해선, Developer Console 에 들어가야된다.


 

 이렇게 되어 있는데에서 Youtube API에 있는 Youtube Data API을 열어야된다.


 페이지를 열게되면, 사용자 인증키를 만들어야된다.


 사용자 인증키를 만들기 위해선, JAVA에서 지원해주는 KeyTool이라는 프로그램을 사용해서 SHA-1 키를 얻어야된다.


 일단, 입력하기 위한 사이트를 찾으면 다음과 같다.


 

 여기 사이트에서 API키을 누르면, 다음과 같은 창이뜬다.



 여기서 Android키를 사용하면, 안드로이드 어플을 제작할 수 있게 된다.


여기서 이제, 안드로이드 패키지의 SHA-1 내용과 패키지 이름을 입력해야된다.


 KeyTool을 찾는게 오래 걸렸는데, JAVA 설치되어 있는 위치에서 bin에 존재한다.


 예을 들어서 그냥 JAVA을 설치한다고 가정한다면, C:/Programe File/JAVA/jdk/bin 에 keytools이 들어 있다.


 이 툴을 이용해서, keytool -list -v -keystore을 이용하면 된다.


 여기서 그림과 같이 mystore.keystore는 .android 폴더에 있는 파일을 이용해서 사용해야된다.


 .android는 기본적으로 C:/users/사용자명/에 .android 라는 폴더에 있으며, 여기서 debug.keystore 에 적용시키면, 뜨게 된다.

Posted by JunkMam
,

 Android Youtube을 제작할려고, 이런 기록을 남긴다.


 Google에서 Youtube API라고 하여, Youtube을 쉽게 연동할 수 있게 하는 장치가 있다.


 이걸 이용해서 안드로이드 Youtube API을 제공하고자 한다.


 먼저, Google 에서 제공하는 API 사이트에 들어가야 된다.[각주:1]


 사이트에 들어가서 다운로드에 가면, YouTubeAndroidPlayerApi-1.2.2.zip 라는 파일이 있다.


 이 파일을 다운 받은 후 라이브러리에 추가해야한다.


 압축을 풀면 다음과 같은 파일들이 존재하게 된다.


 

 docs는 API에 대한 책자 정보를 제공하고, libs는 Android Youtube 라이브러리가 들어가 있다.


 sample은 예제들이 들어가 있으니, 참조하면 도움이 될 것이다.


 먼저 적용하기 위해서 안드로이드 프로젝트를 만든 후.


 프로젝트 폴더의 libs 폴더에 들어가서 libs에 있는 내용을 복사한다.


 프로젝트 폴더 >> app >> libs 안에 라이브러리가 들어가 있어야된다.


 

 이렇게 들어가면 된다.


 이 후에 라이브러리를 제대로 처리하기 위해선, app을 수정해야 된다.


 app의 내용은 다음과 같게 된다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apply plugin: 'com.android.application'android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
 
    defaultConfig {
        applicationId "com.example.sung.android"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
 
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile files('libs/YouTubeAndroidPlayerApi.jar')
}
cs


 여기서 중요한건,

 compile files('libs/YouTubeAndroidPlayerApi.jar')


 이게 없으면 안된다.


 이렇게 하면, Youtube API을 추가 할 수 있게 된다.

  1. 검색 일자 : 2015-10-20 [본문으로]
Posted by JunkMam
,