Skip to content
This repository has been archived by the owner on Sep 10, 2021. It is now read-only.

Commit

Permalink
feat: add methods for joining and leaving live streams (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
szdc committed Aug 28, 2018
1 parent f421ad7 commit bbc15cf
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ const api = new TikTokAPI(params, { signURL });
* [.searchHashtags(params)](#searchhashtagsparams)
* [.listForYouFeed([params])](#listforyoufeedparams)
* [.listFollowingFeed([params])](#listfollowingfeedparams)
* [.joinLiveStream(id)](#joinlivestreamid)
* [.leaveLiveStream(id)](#leavelivestreamid)

#### .loginWithEmail(email, password)

Expand Down Expand Up @@ -340,6 +342,40 @@ api.listFollowingFeed()

See the [feed types](src/types/feed.d.ts) for the complete request/response objects.

#### .joinLiveStream(id)

Joins a live stream.

The `rtmp_pull_url` value can be used with VLC's `Open Network Stream` option.

```javascript
api.joinLiveStream('<room_id>')
.then(res => console.log(res.data.room))
.catch(console.log);

// Outputs:
// { create_time: 1000000000, owner: {...}, stream_url: {...}, title: 'Example', user_count: 1000, ... }

```

See the [live stream types](src/types/live-stream.d.ts) for the complete request/response objects.

#### .leaveLiveStream(id)

Leaves a live stream.

```javascript
api.leaveLiveStream('<room_id>')
.then(res => console.log(res.data.status_code))
.catch(console.log);

// Outputs:
// 0

```

See the [live stream types](src/types/live-stream.d.ts) for the complete request/response objects.

## Resources

* [Reverse engineering the musical.ly API](https://medium.com/@szdc/reverse-engineering-the-musical-ly-api-662331008eb3)
Expand Down
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FollowRequest,
FollowResponse,
HashtagSearchResponse,
JoinLiveStreamResponse,
LikePostRequest,
LikePostResponse,
ListCategoriesRequest,
Expand All @@ -26,6 +27,7 @@ import {
ListForYouFeedResponse,
ListPostsRequest,
ListPostsResponse,
LiveStreamRequest,
LoginRequest,
LoginResponse,
PostCommentRequest,
Expand Down Expand Up @@ -322,6 +324,30 @@ export default class TikTokAPI {
}),
})

/**
* Joins a live stream.
*
* @param id
*/
joinLiveStream = (id: string) =>
this.request.get<JoinLiveStreamResponse | BaseResponseData>('aweme/v1/room/enter/', {
params: <LiveStreamRequest>{
room_id: id,
},
})

/**
* Leaves a live stream.
*
* @param id
*/
leaveLiveStream = (id: string) =>
this.request.get<BaseResponseData>('aweme/v1/room/leave/', {
params: <LiveStreamRequest>{
room_id: id,
},
})

/**
* Transform using JSONBig to store big numbers accurately (e.g. user IDs) as strings.
*
Expand Down
1 change: 1 addition & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './feed';
export * from './follow';
export * from './follower';
export * from './like';
export * from './live-stream';
export * from './login';
export * from './music';
export * from './post';
Expand Down
47 changes: 47 additions & 0 deletions src/types/live-stream.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { BaseResponseData } from './request';
import { CommonUserDetails } from './user';

export interface LiveStreamRequest {
/** The ID of the live stream to join or leave */
room_id: string;
}

export interface JoinLiveStreamResponse extends BaseResponseData {
/** Details about the live stream */
room: LiveStream;
}

export interface LiveStream {
/** The timestamp in seconds when the stream was created */
create_time: number;

/** The timestamp in seconds when this request was processed */
finish_time: number;

/** Details about the user hosting the stream */
owner: CommonUserDetails;

/** The ID of the stream */
room_id: string;

/** ??? */
status: number;

/** The ID used in the stream URL */
stream_id: string;

/** Contains a link to the stream */
stream_url: {
/** A link to the stream source */
rtmp_pull_url: string;

/** The ID used in the stream URL */
sid: string;
};

/** The title of the stream */
title: string;

/** The number of users currently in the stream */
user_count: number;
}
65 changes: 65 additions & 0 deletions test/live-stream.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import MockAdapter from 'axios-mock-adapter';
import { assert } from 'chai';
import { describe, it } from 'mocha';

import TikTokAPI, { BaseResponseData, CommonUserDetails, JoinLiveStreamResponse } from '../src';
import {
loadTestData,
mockConfig,
mockParams,
} from './util';

describe('#joinLiveStream()', () => {
it('a successful response should match the interface', async () => {
const api = new TikTokAPI(mockParams, mockConfig);
const mock = new MockAdapter(api.request);
mock
.onGet(new RegExp('aweme/v1/room/enter/\?.*'))
.reply(200, loadTestData('joinLiveStream.json'), {});

const roomId = '9999999999999999999';
const streamId = '9000000000000000000';
const res = await api.joinLiveStream(roomId);
const expected: JoinLiveStreamResponse = {
extra: {
now: 1000000000000,
},
room: {
create_time: 1000000000,
finish_time: 1000000001,
owner: {} as CommonUserDetails,
room_id: roomId,
status: 0,
stream_id: streamId,
stream_url: {
rtmp_pull_url: `http://pull-flv-l1-mus.pstatp.com/hudong/stream-${streamId}.flv`,
sid: streamId,
},
title: 'Example',
user_count: 1000,
},
status_code: 0,
};
assert.deepStrictEqual(res.data, expected);
});
});

describe('#leaveLiveStream()', () => {
it('a successful response should match the interface', async () => {
const api = new TikTokAPI(mockParams, mockConfig);
const mock = new MockAdapter(api.request);
mock
.onGet(new RegExp('aweme/v1/room/leave/\?.*'))
.reply(200, loadTestData('leaveLiveStream.json'), {});

const roomId = '9999999999999999999';
const res = await api.leaveLiveStream(roomId);
const expected: BaseResponseData = {
extra: {
now: 1000000000000,
},
status_code: 0,
};
assert.deepStrictEqual(res.data, expected);
});
});
20 changes: 20 additions & 0 deletions test/testdata/joinLiveStream.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extra": {
"now": 1000000000000
},
"room": {
"create_time": 1000000000,
"finish_time": 1000000001,
"owner": {},
"room_id": 9999999999999999999,
"status": 0,
"stream_id": 9000000000000000000,
"stream_url": {
"rtmp_pull_url": "http://pull-flv-l1-mus.pstatp.com/hudong/stream-9000000000000000000.flv",
"sid": 9000000000000000000
},
"title": "Example",
"user_count": 1000
},
"status_code": 0
}
6 changes: 6 additions & 0 deletions test/testdata/leaveLiveStream.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extra": {
"now": 1000000000000
},
"status_code": 0
}

0 comments on commit bbc15cf

Please sign in to comment.