반응형

 

 

youtube API 사용해보기

개요 조금 시간이 지났지만 Twitch라는 스트리밍 사이트의 화질이 안좋아지고 나서 몇몇 인터넷 방송인들이 youtube와 twitch를 동시방영을 하는 경우가 생기기 시작한 시점에서 youtube에서 화질이 좋

history-store.tistory.com


이전 포스팅에서 조사했던것 처럼 Twitch의 채팅을 끌어오고 싶은 마음에  Twitch API를 이용하여서 해당 문제를 해결하고 싶어서 간단한 조사를 해보았다.

 

 

Twitch API

Twitch API

dev.twitch.tv

해당 페이지가 Twitch API의 문서 페이지이다.

채팅을 불러오는 방법은 생각보다는 간단하게 흘러갔다.

 

인덱스에

Embedding Chat

을 치고 들어가면

<iframe src="https://www.twitch.tv/embed/<channel>/chat?parent=<parent>"
        height="<height>"
        width="<width>">
</iframe>

으로 간단하게 표현 가능하게 되어 있다.

 

매개변수에 대해서는 위와 같이 설정되어져 있다.

 

channel의 이름은 흔히 방송 채널로 들어가면 주소를 보면 알수 있는 닉네임을 가리킨다.

보통 twitch.tv/<채널명> 으로 구성되어 있다.

 

하지만 일일이 유저가 트위치로 가서 찾는것은 이상하다고 생각하여서 알수 있는 방법이 없을까 조사를 해보니

Twitch API Reference

가 있어서 살펴보니

Search Channels

라는 기능을 사용하면 트위치에서 검색 기능과 같은 기능을 사용할수 있어서 해당기능을 사용하고자 합니다.

레퍼런스를 살펴보면 사용 방법은

curl -X GET 'https://api.twitch.tv/helix/search/channels?query=loserfruit' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz'

의 데이터를 보내면 결과로

{
  "data": [
    {
      "broadcaster_language": "en",
      "broadcaster_login": "loserfruit",
      "display_name": "Loserfruit",
      "game_id": "498000",
      "game_name": "House Flipper",
      "id": "41245072",
      "is_live": false,
      "tag_ids": [],
      "tags": [],
      "thumbnail_url": "https://static-cdn.jtvnw.net/jtv_user_pictures/fd17325a-7dc2-46c6-8617-e90ec259501c-profile_image-300x300.png",
      "title": "loserfruit",
      "started_at": ""
    },
    ...
  ],
  "pagination": {
    "cursor": "Mg=="
  }
}

의 데이터가 응답한다고 한다

 

여기서 의문이 인증클라이언트 id인데

 

클라이언트 id 의 경우는 twitch developers에 로그인을 한뒤에

오른쪽 위의 Yout Console을 클릭해서 들어가보면

와 같은 창이 나오는데 응용 프로그램을 등록을 한뒤에 관리버튼으로 들어가면 클라이언트 아이디를 확인할수 있다.

 

인증의 경우에는

의 마지막을 선택해 들어가서 보면

인증을 얻는 방식의 예제를 살펴보면

curl -X POST 'https://id.twitch.tv/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=<your client id goes here>&client_secret=<your client secret goes here>&grant_type=client_credentials'

으로 통신을 하게 되면

{
  "access_token": "jostpf5q0puzmxmkba9iyug38kjtg",
  "expires_in": 5011271,
  "token_type": "bearer"
}

의 데이터를 받아서 엑세스 토큰을 구할수 있다.

 

그런데 여기서도 알수 없는게 하나 존재하는데 그것은 클라이언트 시크릿이라는 것인데

그것은 위의 콘솔 페이지로 들어가서

등록한 응용 프로그램에 들어가면 클라이언트 시크릿을 생성하는 것이 가능해진다.

 

가볍게 postman으로 토큰을 얻고 스트리머 류제홍을 검색을 하게 되면

여러 검색결과가 나오지만

{
    "data": [
        {
            "broadcaster_language": "ko",
            "broadcaster_login": "wpghd321",
            "display_name": "류제홍_",
            "game_id": "21779",
            "game_name": "League of Legends",
            "id": "128035304",
            "is_live": false,
            "tag_ids": [],
            "tags": [
                "한국어"
            ],
            "thumbnail_url": "https://static-cdn.jtvnw.net/jtv_user_pictures/adb62723-be04-4b89-bae9-15c8ac9ecf54-profile_image-300x300.png",
            "title": "야심한새벽",
            "started_at": ""
        },

와 같이 broadcaster_login으로 아이디를 확인 할 수 있다.

반응형

'토이프로젝트' 카테고리의 다른 글

토이프로젝트 - PIViewer(4) backend  (0) 2023.11.27
토이프로젝트 - PIViewer(3)  (0) 2023.11.12
토이프로젝트 - PIViewer(2)  (0) 2023.11.10
토이프로젝트 - PIViewer(1)  (0) 2023.11.10
youtube API 사용해보기  (0) 2023.10.30
반응형

개요

조금 시간이 지났지만 Twitch라는 스트리밍 사이트의 화질이 안좋아지고 나서 몇몇 인터넷 방송인들이 youtube와 twitch를 동시방영을 하는 경우가 생기기 시작한 시점에서

youtube에서 화질이 좋은 버전으로 보면 1080p로 좋은 화질로 시청하는것이 가능하지만 치명적인 약점으로 방송과 채팅간의 딜레이가 상당히 길기 때문에 실시간 소통이라는 느낌을 받지 못한다.

그렇다고 해당 약점을 해결하고자 Twitch에서 시청을 하기에는 720p는 확실히 1080p에 비해서는 화질이 너무 안좋아서 고화질 게임을 할때 문제가 발생한다.

그렇기 때문에 youtube영상으로 보면서 twitch의 댓글을 사용하는 식으로 고화질로 사용하거나

VPN을 사용해서 해외 서버로 접속해서 해외 ;트위치의 서비스를 이용하는 방식으로 우회 이용하는 방식으로 나름 고화질의 서비스를 받기 위해 이런 저런 방법을 사용을 한다.

 

VPN을 제외한 youtube와 twitch의 동시에 사용하는 방법의 경우에 여러창을 사용하는 불편함이 있기 때문에

한번 둘의 서비스를 같이 사용하는 방법이 있으면 좋지 않을까에서 해당 토이 프로젝트를 진행해보고자 한다.

 


youtube API의 경우에는 google cloud 서비스를 이용

 

클라우드 컴퓨팅 서비스 | Google Cloud

데이터 관리, 하이브리드 및 멀티 클라우드, AI와 머신러닝 등 Google의 클라우드 컴퓨팅 서비스로 비즈니스 당면 과제를 해결하세요.

cloud.google.com

로그인을 한뒤에 오른쪽 위를 보면 콘솔 버튼을 클릭하게 되

여러 서비를 이용하는 것이 가능하다.

API 및 서비스를 클릭해서 찾아보면 youtube 관련 API는 총 3개 존재한다.

왼쪽 탭의 API 및 서비스 아래에 존재하는 사용자 인증 정보를 통해서 API키 및 OAuth 2.0 클라이언트 ID를 만드는것이 가능하다.

기본적으로 API키만 필요하지만 경우에 따라서 OAuth 2.0 클라이언트 ID가 필요한 케이스도 존재하니 필요에 따라서 생성하여 사용하면 될 것 같다.


사족을 끝내고 다시 youtube로 들어가면 google에서 자세한 라이브러리를 제공하고 있기 때문에 필요에 따라서 찾아 사용하면 될 것 같아 보인다.

이번에 내가 필요한 기능은 youtube의 필요한 채널이 생방송 중인지 체크를 할 필요가 있기 때문에 여러 기능을 찾아 보니 구현 가능한 흐름으로는

  1. [검색 기능]을 통해
  2. 알고 싶은 채널의 [채널 ID]를 구한 뒤
  3. 해당 [채널 ID]를 이용해서 해당 채널이 생방송 중인지 확인
  4. 검색하는 과정에서 생방송의 [비디오 ID]를 검색

해당 흐름을 통해서 원하는 기능을 구현하는 것이 가능할것으로 생각된다.

반응형

'토이프로젝트' 카테고리의 다른 글

토이프로젝트 - PIViewer(4) backend  (0) 2023.11.27
토이프로젝트 - PIViewer(3)  (0) 2023.11.12
토이프로젝트 - PIViewer(2)  (0) 2023.11.10
토이프로젝트 - PIViewer(1)  (0) 2023.11.10
Twitch API 간단 사용해보기  (0) 2023.11.10
반응형

 

 

이벤트 처리하기 – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org


  • React의 이벤트는 소문자 대신 캐멀 케이스(camelCase)를 사용합니다.
  • JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달합니다.

예를 들어, HTML은 다음과 같습니다.

<button onclick="activateLasers()">
  Activate Lasers
</button>

React에서는 약간 다릅니다.

<button onClick={activateLasers}>
  Activate Lasers
</button>

또 다른 차이점으로, React에서는 false를 반환해도 기본 동작을 방지할 수 없습니다. 반드시 preventDefault를 명시적으로 호출해야 합니다. 예를 들어, 일반 HTML에서 폼을 제출할 때 가지고 있는 기본 동작을 방지하기 위해 다음과 같은 코드를 작성할 수 있습니다.

<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

React에서는 다음과 같이 작성할 수 있습니다.

function Form() {
  // event 든 e든 상관 없음
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

여기서 e는 합성 이벤트입니다. React는 W3C 명세에 따라 합성 이벤트를 정의하기 때문에 브라우저 호환성에 대해 걱정할 필요가 없습니다.

 

React를 사용할 때 DOM 엘리먼트가 생성된 후 리스너를 추가하기 위해 addEventListener를 호출할 필요가 없습니다. 대신, 엘리먼트가 처음 렌더링될 때 리스너를 제공하면 됩니다.


class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ON을 틀릭하면 OFF으로 바뀐다.

JSX 콜백 안에서 this의 의미에 대해 주의해야 합니다. JavaScript에서 클래스 메서드는 기본적으로 바인딩되어 있지 않습니다. this.handleClick을 바인딩하지 않고 onClick에 전달하였다면, 함수가 실제 호출될 때 this는 undefined가 됩니다.

이는 React만의 특수한 동작이 아니며, JavaScript에서 함수가 작동하는 방식의 일부입니다. 일반적으로 onClick={this.handleClick}과 같이 뒤에 ()를 사용하지 않고 메서드를 참조할 경우, 해당 메서드를 바인딩 해야 합니다.

bind를 호출하는 것이 불편하다면, 이를 해결할 수 있는 두 가지 방법이 있습니다. 콜백을 올바르게 바인딩하기 위해 퍼블릭 클래스 필드 문법을 활용할 수 있다.

class LoggingButton extends React.Component {
  // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
  handleClick = () => {
    console.log('this is:', this);
  };

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

클래스 필드 문법을 사용하고 있지 않다면, 콜백에 화살표 함수를 사용하는 방법도 있습니다.

class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
    return (
      <button onClick={() => this.handleClick()}>
        Click me
      </button>
    );
  }
}

이 문법의 문제점은 LoggingButton이 렌더링될 때마다 다른 콜백이 생성된다는 것입니다. 대부분의 경우 문제가 되지 않으나, 콜백이 하위 컴포넌트에 props로서 전달된다면 그 컴포넌트들은 추가로 다시 렌더링을 수행할 수도 있습니다. 이러한 종류의 성능 문제를 피하고자, 생성자 안에서 바인딩하거나 클래스 필드 문법을 사용하는 것을 권장합니다.

이벤트 핸들러에 인자 전달하기

루프 내부에서는 이벤트 핸들러에 추가적인 매개변수를 전달하는 것이 일반적입니다. 예를 들어, id가 행의 ID일 경우 다음 코드가 모두 작동합니다.

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

위 두 줄은 동등하며 각각 화살표 함수와 Function.prototype.bind를 사용합니다.

class MyComponent extends React.Component {
  handleClick = (arg1, arg2, event) => {
    // arg1, arg2, 그리고 event 객체는 인자로 전달됨
    console.log(arg1, arg2, event);
  }

  render() {
    return (
      // <button onClick={(e) => this.handleClick(this, '인자1', '인자2')}>클릭</button>
      <button onClick={this.handleClick.bind(this, '인자1', '인자2')}>클릭</button>
    );
  }
}

두 경우 모두 React 이벤트를 나타내는 e 인자가 ID 뒤에 두 번째 인자로 전달됩니다. 화살표 함수를 사용하면 명시적으로 인자를 전달해야 하지만 bind를 사용할 경우 추가 인자가 자동으로 전달됩니다.

반응형
반응형

https://ko.legacy.reactjs.org/docs/conditional-rendering.html

 

조건부 렌더링 – React

A JavaScript library for building user interfaces

ko.legacy.reactjs.org


React에서 조건부 렌더링은 JavaScript에서의 조건 처리와 같이 동작합니다. if 나 조건부 연산자 와 같은 JavaScript 연산자를 현재 상태를 나타내는 엘리먼트를 만드는 데에 사용하세요. 그러면 React는 현재 상태에 맞게 UI를 업데이트할 것입니다.

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

이제 사용자의 로그인 상태에 맞게 위 컴포넌트 중 하나를 보여주는 Greeting 컴포넌트를 만듭니다.

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

const root = ReactDOM.createRoot(document.getElementById('root')); 
// Try changing to isLoggedIn={true}:
root.render(<Greeting isLoggedIn={false} />);

엘리먼트 변수

로그아웃과 로그인 버튼을 나타내는 두 컴포넌트가 있다고 가정해 보세요.

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

이 컴포넌트는 현재 상태에 맞게 <LoginButton />이나 <LogoutButton />을 렌더링합니다. 또한 이전 예시에서의 <Greeting />도 함께 렌더링합니다.

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

const root = ReactDOM.createRoot(document.getElementById('root')); 
root.render(<LoginControl />);

로그인 버튼을 누르면 아래와 같이 전환된다.

 

반응형

+ Recent posts