반응형
반응형

구글에서 제공해주는 API와 client 라이브러리를 활용하여 유튜브 라이브 스트리밍의 채팅들을 수집하고자 합니다.

스트리머들의 화면에서 채팅 내용이 별도로 보이는 것에서 궁금하여 진행해 보았고, 이후 어떤 것을 할지는 차차 고민해보도록 하죠

우선 유튜브 개발자 사이트를 보면, 유튜브 관련 API는 크게 아래 3가지가 있습니다.

  • YouTube Data API (v3)
    • 동영상 업로드, 재생목록 생성, 관리 등 YouTube 기능을 애플리케이션에 추가할 수 있습니다.
  • YouTube 분석 API
    • YouTube 동영상 및 채널의 시청 통계, 인기도 측정항목 등을 검색하세요.
  • YouTube Live Streaming API
    • 실시간 YouTube 방송을 예약하고 방송 동영상 스트림을 관리합니다.

여기서 Data API(V3)와 Live Streaming API를 이용하여, 유튜브 라이브 스트리밍에서 URL 내 video id를 가지고 실시간 채팅을 주기적으로 가져와 볼 계획입니다.

 

10초 주기로 가져오게끔 해볼 예정인데, 이는 하루에 1만건 제한이 있는 것으로 보이기에 제한사항에 따라 바꾸면 될 것 같습니다. (참고 : https://developers.google.com/youtube/v3/determine_quota_cost?hl=ko)

 

2가지를 활용하는 이유가, 실시간 채팅에 대한 ID가 필요한데 이 실시간 채팅 ID에 대한 정보를 가져오기 위해 Data API(v3)를 이용하여 실시간 채팅 ID를 가져온 후 Live Streaming API로 채팅 내용을 가져오는 형태로 진행했습니다.

실시간 채팅 리스트에 대한 API 가이드를 보면 요청 시 liveChatId가 필요한데, 이는 video에 대한 API 가이드에서 응답 중 'items'부분에 video 리소스 부분을 보면 "liveStreamingDetails"에 "activeLiveChatId"가 있더라구요. 실시간 채팅 ID에 대해 가장 얻기 쉬운 방법이 유튜브 URL에 있는 video id인 점에서 착안하여 해당 방법으로 진행했습니다.

 


 

코딩에 앞서 api key를 획득하기 위한 방법을 먼저 설명하자면, google developer console 에서 youtube data api 사용 설정 후 키 발급을 진행하면 되며 아래와 같습니다. (프로젝트 생성은 생략)

 

프로젝트 생성 후 'API 및 서비스 사용 설정' 버튼을 클릭하여 api 검색을 위한 페이지로 들어간다.
위쪽 가운데에 있는 검색란에 'youtube'라고 검색 후
Youtube Data API v3를 클릭하고 사용 설정하면 API 사용에 대한 프로젝트 설정이 완료된다
이후 '사용자 인증 정보' 페이지로 이동하여 '사용자 인증 정보 만들기'에서 API키를 클릭하면
API키 생성이 완료됩니다.

 


 

자, 그럼 이제 python으로 라이브 스트리밍에 대한 video id를 기반으로 채팅을 가져오는 코드를 작성해보죠.

pip를 이용하여 별도로 사용한 python 패키지는 google api client 패키지(https://developers.google.com/explorer-help/code-samples#python)만 사용했습니다.

 

import argparse
import configparser
import csv
import time

# import google api client
import googleapiclient.discovery
import googleapiclient.errors


# api 사용을 위한 기본 세팅(api_key는 config.ini 파일에 따로 작성)
config = configparser.ConfigParser()
config.read('./config.ini')
api_key = config['KEY']['ApiKey']
api_service_name = "youtube"
api_version = "v3"
youtube = googleapiclient.discovery.build(
        api_service_name, api_version, developerKey=api_key)


# 채팅 내용 CSV로 저장(유튜브 채널 ID_비디오 ID.csv 파일로 생성)
def convertDicToCSV(dicList, video_id, channel_id)->None:
    fieldnames = ['time','message','user']
    file_name = f"{channel_id}_{video_id}.csv"

    with open(file_name, "a", encoding='utf-8-sig', newline="") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        # writer.writeheader()
        for item in dicList:
            _time = item["snippet"]["publishedAt"]
            _message = item["snippet"]["textMessageDetails"]["messageText"]
            _user = item["authorDetails"]["displayName"]
            writer.writerow({'time':_time, 'message':_message, 'user':_user})
    csvfile.close()

    return


# 비디오 정보 가져오기
def get_livechat_id(video_id):
    request = youtube.videos().list(
        part="liveStreamingDetails,snippet,status",
        id=video_id
    )
    response = request.execute()
    channel_id = response["items"][0]["snippet"]["channelId"]
    chat_id = response["items"][0]["liveStreamingDetails"]["activeLiveChatId"]
    result = {"channel_id":channel_id, "chat_id":chat_id}

    return result


# main문
def main(video_id):
    _get_video_info = get_livechat_id(video_id) # 유튜브 비디오 아이디로 비디오 관련 정보 획득
    _chat_id = _get_video_info["chat_id"] # 실시간 채팅 ID 획득
    _channel_id = _get_video_info["channel_id"] # CSV 파일 이름에 채널 ID 추가를 위한 채널 ID 획득
    
    page_token = ""
    polling_time = 10000

    while True:
        request = youtube.liveChatMessages().list(
            part="snippet,authorDetails",
            liveChatId=_chat_id,
            pageToken=page_token
        )
        response = request.execute()
        page_token = response["nextPageToken"] # 다음 채팅 정보 획득을 위한 토큰 획득
        convertDicToCSV(response["items"], video_id, _channel_id) # 실시간 채팅 획득 내용을 CSV에 작성
        
        # 
        interval_polling_time = response["pollingIntervalMillis"]
        if interval_polling_time > polling_time:
            time.sleep(interval_polling_time / 1000)
        else:
            time.sleep(polling_time / 1000)


# python 실행 시 스트리밍 video id를 argument로 받아서 실행
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-v', help=' : Please set youtube video id (https://www.youtube.com/watch?v=[video_id])')
    args = parser.parse_args()
    main(args.v)

 

 

실행 결과

유튜브에서 스트리밍 중인 뉴스로 테스트를 진행했고, 아래와 같이 유튜브 url 내 video id를 argument로 실행하면 10초 주기로 가져와서 csv파일에 저장합니다. (현재는 while true라 ctrl+c로 python 강제종료 ㅎㅎ)

 

유튜브 라이브 스트리밍 url('https://www.youtube.com/watch?v=[video id]')에서 video id를 가지고

 

python에 argument로 실행하면

 

csv파일이 생기고

 

시간과 채팅 내용, 채팅작성자를 지속적으로 작성합니다.

 

 

반응형
반응형

문제

Given a string s, return the longest palindromic substring in s.

 

Example 1:

Input: s = "babad"
Output: "bab"
Explanation: "aba" is also a valid answer.

Example 2:

Input: s = "cbbd"
Output: "bb"

 

Constraints:

  • 1 <= s.length <= 1000
  • s consist of only digits and English letters.

 

 

https://leetcode.com/problems/longest-palindromic-substring/

 

 

풀이

회문인지 조사할 중심점을 잡아서, 중심점이 홀수 일 때와 짝수 일 때를 나눠서 길이를 비교하도록 했다.

for문이나 while문 하나로 할 수 있는 방법이 없나 고민해봤으나, 현재로써는 이 방법이 최선인 듯 하다.

 

 

 

코드

class Solution {
    public String longestPalindrome(String s) {
        String res = new String();
        int maxLen = 0;
        
        for(int i = 0; i < s.length(); i++) {
        	int len = Math.max(find(s, i, i), find(s, i, i+1));
        	if(len >= maxLen) {
        		res = s.substring(i - (len / 2), i + (len / 2) + (len % 2) + 1);
        		maxLen = len;
        	}
        }
		return res;
    }
    
    public int find(String s, int left, int right) {
		int start = 0, end = 0;
		while(left >= 0 && right < s.length()) {
			if(s.charAt(left) == s.charAt(right)) {
				start = left;
				end = right;
				left--;
				right++;
				continue;
			}
			break;
		}
		return end - start;
	}
}

 

 

결과

Runtime: 50 ms, faster than 61.16% of Java online submissions for Longest Palindromic Substring.
Memory Usage: 45.2 MB, less than 39.24% of Java online submissions for Longest Palindromic Substring.

 

반응형

'LeetCode' 카테고리의 다른 글

7. Reverse Integer  (0) 2024.11.10
6. Zigzag Conversion  (1) 2024.11.05
4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
반응형

문제

  • Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.
    Input: nums1 = [1,3], nums2 = [2]
    Output: 2.00000
    Explanation: merged array = [1,2,3] and median is 2.
    
    Example 2:
    • nums1.length == m
    • nums2.length == n
    • 0 <= m <= 1000
    • 0 <= n <= 1000
    • 1 <= m + n <= 2000
    • -106 <= nums1[i], nums2[i] <= 106
  • Constraints:
  • Input: nums1 = [1,2], nums2 = [3,4] Output: 2.50000 Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
  • Example 1:
  • The overall run time complexity should be O(log (m+n)).

 

https://leetcode.com/problems/median-of-two-sorted-arrays/

 

 

풀이

이미 정렬된 두개의 배열을 준다고 하여, 그냥 하나로 합쳐서 풀었다.

 

 

 

코드

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int i = 0, j = 0, z = 0;
        
        int[] nums = new int[nums1.length + nums2.length];
        while (i < nums1.length && j < nums2.length) {
            nums[z++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
        }
         
        if (i == nums1.length) {
            for (; z < nums.length; z++) {
                nums[z] = nums2[j++];
            }
        }
        else {
            for (; z < nums.length; z++) {
                nums[z] = nums1[i++];
            }
        }
        
         
        if (nums.length % 2 == 0) {
        	return (double)(nums[nums.length / 2 - 1] + nums[nums.length / 2]) / 2;
        }
        else {
        	return nums[nums.length / 2]; 
        }
    }
}

 

 

결과

Runtime: 4 ms, faster than 60.76% of Java online submissions for Median of Two Sorted Arrays.
Memory Usage: 49.5 MB, less than 13.27% of Java online submissions for Median of Two Sorted Arrays.

 

반응형

'LeetCode' 카테고리의 다른 글

6. Zigzag Conversion  (1) 2024.11.05
5. Longest Palindromic Substring  (0) 2022.02.14
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
9. Palindrome Number  (0) 2022.01.16
반응형

문제

Given a string s, find the length of the longest substring without repeating characters.

 

Example 1:

Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.

 

Constraints:

  • 0 <= s.length <= 5 * 104
  • s consists of English letters, digits, symbols and spaces.

 

https://leetcode.com/problems/longest-substring-without-repeating-characters/

 

Longest Substring Without Repeating Characters - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

 

풀이

이전에는 String에 넣고, 중복된 문자가 있는 경우 다시 시작했던 index의 다음부터 다시 비교하다 보니 시간과 메모리 소요가 컸다.

최대한 반복하지 않고, 변수도 줄일 생각으로 문제를 다시 한번 풀어보았다.

이번에는, 가면서 중복된 문자가 있을 경우 start를 1증가시켜서 다시 비교해 나가는 방식으로 코드를 작성했다.

substring을 사용하여 현재 index의 문자가 없는 부분까지 start를 증가시킨 후, 다음 index부터 비교하도록 하여 반복 시간과 메모리 사용량을 줄였다.

 

 

코드

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int start = 0;
        int idx = 0;
        int maxlength = 0;
        
        while(idx < s.length()) {
        	if(start > idx) {
        		break;
        	}
        	
        	if(!s.substring(start, idx).contains(""+s.charAt(idx))) {
        		idx++;
        		maxlength = (maxlength - (idx - start) > 0) ? maxlength : (idx - start);
        		continue;
        	}
        	
        	start++;
        }
        
        return maxlength;
    }
}

 

 

결과

  • AS-IS
Runtime: 534 ms, faster than 5.01% of Java online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 141.3 MB, less than 5.06% of Java online submissions for Longest Substring Without Repeating Characters.

 

  • TO-BE
Runtime: 13 ms, faster than 40.04% of Java online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 40 MB, less than 49.03% of Java online submissions for Longest Substring Without Repeating Characters.

 

반응형

'LeetCode' 카테고리의 다른 글

5. Longest Palindromic Substring  (0) 2022.02.14
4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
9. Palindrome Number  (0) 2022.01.16
2. Add Two Numbers  (0) 2022.01.16
반응형

문제

Given a string s, find the length of the longest substring without repeating characters.

 

Example 1:

Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.

 

Constraints:

  • 0 <= s.length <= 5 * 104
  • s consists of English letters, digits, symbols and spaces.

 

https://leetcode.com/problems/longest-substring-without-repeating-characters/

 

Longest Substring Without Repeating Characters - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

 

풀이

하나씩 비교해 가면서 중복된 문자가 있을 경우, start를 1증가시켜서 다시 비교해 나가는 방식으로 코드를 작성했다.

임시로 String을 저장해 놓고 중복된 문자가 있는 경우 기존 문자열(res)보다 큰 경우에 res에 저장하도록 했는데, 문제를 풀기는 했지만 속도와 메모리를 너무 많이 사용한다.

한번의 loop로 끝낼 수 있는 방법을 찾아서 다시 한번 해봐야겠다.

 

 

코드

class Solution {
	public int lengthOfLongestSubstring(String s) {
		String res = "";
		String tmp = "";
        
		int start = 0;
		int idx = 0;
        
		while(idx < s.length()) {
			if(start > idx) {
				break;
			}
			if(!tmp.contains("" + s.charAt(idx))) {
				tmp += s.charAt(idx++);
				if(tmp.length() > res.length()) res = tmp.toString();
				continue;
			}
			start++;
			idx = start;
			tmp = "";
		}
        
		return res.length();
	}
}

 

 

결과

Runtime: 534 ms, faster than 5.01% of Java online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 141.3 MB, less than 5.06% of Java online submissions for Longest Substring Without Repeating Characters.

 

 

반응형

'LeetCode' 카테고리의 다른 글

4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
9. Palindrome Number  (0) 2022.01.16
2. Add Two Numbers  (0) 2022.01.16
1. Two Sum  (0) 2022.01.16
반응형

문제

  • Given an integer x, return true if x is palindrome integer.
    • For example, 121 is a palindrome while 123 is not.

    Input: x = 121
    Output: true
    Explanation: 121 reads as 121 from left to right and from right to left.
    
    Example 2:Example 3:
    • -231 <= x <= 231 - 1
  • Constraints:
  • Input: x = 10 Output: false Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
  • Input: x = -121 Output: false Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
  • Example 1:
  • An integer is a palindrome when it reads the same backward as forward.

 

https://leetcode.com/problems/palindrome-number/

 

Palindrome Number - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

풀이

x값을 String으로 변경하여 Stirng을 reverse 시킨 값과 비교하도록 했다.

 

 

코드

class Solution {
	public boolean isPalindrome(int x) {
		String s = Integer.toString(x);
		StringBuilder sb = new StringBuilder(Integer.toString(x));
        
		return s.equals(sb.reverse().toString());
	}
}

 

 

결과

Runtime: 15 ms
Memory Usage: 44.2 MB

 

반응형

'LeetCode' 카테고리의 다른 글

4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
2. Add Two Numbers  (0) 2022.01.16
1. Two Sum  (0) 2022.01.16
반응형

문제

  • You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.
    Input: l1 = [2,4,3], l2 = [5,6,4]
    Output: [7,0,8]
    Explanation: 342 + 465 = 807.
    
    Example 2:Example 3:
    • The number of nodes in each linked list is in the range [1, 100].
    • 0 <= Node.val <= 9
    • It is guaranteed that the list represents a number that does not have leading zeros.
  • Constraints:
  • Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] Output: [8,9,9,9,0,0,0,1]
  • Input: l1 = [0], l2 = [0] Output: [0]
  • Example 1:
  • You may assume the two numbers do not contain any leading zero, except the number 0 itself.

 

https://leetcode.com/problems/add-two-numbers/

 

Add Two Numbers - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

 

풀이

return용 노드 생성 후 해당 노드를 복사하여 사용했다.

l1노드나 l2노드를 끝까지 돌면서 더한 값의 나머지를 복사용 노드의 next에 넣고, 현재 가리키는 노드를 다음으로 이동해가며 반복했다.

while문이 끝나고 덧셈의 마지막 carry가 있는 경우 한번 더 복사용 노드에 넣고, return 시 return용 노드의 다음을 return하도록 했다. (응답용 노드의 다음부터 더한 값의 나머지를 넣었기 때문)

 

 

코드

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
	public ListNode addTwoNumbers(ListNode l1, ListNode l2) {    
		ListNode res = new ListNode(0);
		ListNode tmp = res;
		int carry = 0;
		
		while(l1 != null || l2 != null) {
			int add = (l1 != null? l1.val : 0) + (l2 != null? l2.val : 0) + carry;
			carry = add / 10;
			add = add % 10;
			tmp.next = new ListNode(add);
			tmp = tmp.next;
			if(l1 != null)l1 = l1.next;
			if(l2 != null)l2 = l2.next;
		}
		
		if(carry != 0) {
			tmp.next = new ListNode(carry);
		}
		
		res = res.next;

		return res;
	}
}

 

 

결과

Runtime: 3 ms
Memory Usage: 45 MB

 

 

반응형

'LeetCode' 카테고리의 다른 글

4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
9. Palindrome Number  (0) 2022.01.16
1. Two Sum  (0) 2022.01.16
반응형

문제

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

 

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

 

Constraints:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • Only one valid answer exists.

 

https://leetcode.com/problems/two-sum/

 

Two Sum - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

 

풀이

이중 for문을 통해 한번씩 비교해 나가는 방법을 이용했다.

답이 되는 경우가 한가지 밖에 없다고 해서 배열의 0번 숫자와 1~끝까지 더해보고, 1번 숫자와 2~끝가지 더해보는 식으로 이중 for문을 이용했다.

for문을 돌리면서 Map에 target에서 nums배열에 있는 값을 뺀 결과와 인덱스를 저장해 놓고, 다음 nums배열의 숫자가 Map에 있는지 contiains를 통해 확인하는 형식으로 하면 for문을 하나만 사용할 수 있을 것 같긴 하다.

 

 

코드

class Solution {
	public int[] twoSum(int[] nums, int target) {
		int[] res = new int[2];
		boolean flage = false;
		for(int i = 0; i < nums.length; i++) {
			res[0] = i;
			for(int j = i+1; j < nums.length; j++) {
				if(nums[res[0]] + nums[j] == target) {
					res[1] = j;
					flage = true;
					break;
				}
			}
			if(flage) {
				break;
			}
		}

		return res;
	}
}

 

 

결과

Runtime: 60 ms
Memory Usage: 39 MB

 

반응형

'LeetCode' 카테고리의 다른 글

4. Median of Two Sorted Arrays  (0) 2022.02.06
3. Longest Substring Without Repeating Characters 수정  (0) 2022.01.21
3. Longest Substring Without Repeating Characters  (0) 2022.01.16
9. Palindrome Number  (0) 2022.01.16
2. Add Two Numbers  (0) 2022.01.16

+ Recent posts