Skip to content
This repository was archived by the owner on Mar 19, 2021. It is now read-only.

Commit e66bd2c

Browse files
committed
Stream audio from PS4
1 parent 2091ae6 commit e66bd2c

1 file changed

Lines changed: 155 additions & 0 deletions

File tree

cli/src/audiostream.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* This file is part of Chiaki.
3+
*
4+
* Chiaki is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Chiaki is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <chiaki-cli.h>
19+
20+
#include <chiaki/session.h>
21+
#include <chiaki/opusdecoder.h>
22+
#include <chiaki/audioreceiver.h>
23+
24+
#include <argp.h>
25+
#include <string.h>
26+
27+
#include <chiaki/base64.h>
28+
#include <unistd.h>
29+
30+
static char doc[] = "Request for PS4 audiostream.";
31+
32+
#define ARG_KEY_HOST 'h'
33+
#define ARG_KEY_REGISTKEY 'r'
34+
#define ARG_KEY_MORNING 'm'
35+
36+
static struct argp_option options[] = {
37+
{ "host", ARG_KEY_HOST, "Host", 0, "Host to request audiostream from", 0 },
38+
{ "registkey", ARG_KEY_REGISTKEY, "RegistKey", 0, "PS4 registration key", 0 },
39+
{ "morning", ARG_KEY_MORNING, "Morning", 0, "PS4 morning encoded in base64", 0 },
40+
{ 0 }
41+
};
42+
43+
typedef struct arguments
44+
{
45+
const char *host;
46+
const char *registkey;
47+
const char *morning;
48+
} Arguments;
49+
50+
static int parse_opt(int key, char *arg, struct argp_state *state)
51+
{
52+
Arguments *arguments = state->input;
53+
54+
switch(key)
55+
{
56+
case ARG_KEY_HOST:
57+
arguments->host = arg;
58+
break;
59+
case ARG_KEY_REGISTKEY:
60+
arguments->registkey = arg;
61+
break;
62+
case ARG_KEY_MORNING:
63+
arguments->morning = arg;
64+
break;
65+
case ARGP_KEY_ARG:
66+
argp_usage(state);
67+
break;
68+
default:
69+
return ARGP_ERR_UNKNOWN;
70+
}
71+
72+
return 0;
73+
}
74+
75+
static struct argp argp = { options, parse_opt, 0, doc, 0, 0, 0 };
76+
77+
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user)
78+
{
79+
fprintf(stderr, "%s", (char *)buf);
80+
}
81+
82+
CHIAKI_EXPORT int chiaki_cli_cmd_audiostream(ChiakiLog *log, int argc, char *argv[])
83+
{
84+
Arguments arguments = { 0 };
85+
error_t argp_r = argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &arguments);
86+
if(argp_r != 0)
87+
return 1;
88+
89+
if(!arguments.host)
90+
{
91+
fprintf(stderr, "No host specified, see --help.\n");
92+
return 1;
93+
}
94+
if(!arguments.registkey)
95+
{
96+
fprintf(stderr, "No registration key specified, see --help.\n");
97+
return 1;
98+
}
99+
if(!arguments.morning)
100+
{
101+
fprintf(stderr, "No morning specified, see --help.\n");
102+
return 1;
103+
}
104+
if(strlen(arguments.registkey) > 8)
105+
{
106+
fprintf(stderr, "Given registkey is too long.\n");
107+
return 1;
108+
}
109+
110+
ChiakiConnectInfo chiaki_connect_info;
111+
size_t morning_size = sizeof(chiaki_connect_info.morning);
112+
uint8_t morning[morning_size];
113+
chiaki_base64_decode(arguments.morning, strlen(arguments.morning), morning, &morning_size);
114+
memcpy(chiaki_connect_info.morning, morning, morning_size);
115+
chiaki_connect_info.host = arguments.host;
116+
memcpy(chiaki_connect_info.regist_key, arguments.registkey, sizeof(chiaki_connect_info.regist_key));
117+
118+
ChiakiConnectVideoProfile video_profile;
119+
// From what it seems like, PS4 does not allow for audio-only stream.
120+
// So it's necessary to also request for video stream. This needs to
121+
// be confirmed though.
122+
video_profile.width = 640;
123+
video_profile.height = 360;
124+
video_profile.max_fps = 30;
125+
video_profile.bitrate = 128;
126+
chiaki_connect_info.video_profile = video_profile;
127+
128+
ChiakiSession session;
129+
ChiakiErrorCode err;
130+
err = chiaki_session_init(&session, &chiaki_connect_info, NULL);
131+
if(err != CHIAKI_ERR_SUCCESS)
132+
return 2;
133+
134+
ChiakiOpusDecoder opus_decoder;
135+
chiaki_opus_decoder_init(&opus_decoder, NULL);
136+
chiaki_opus_decoder_set_cb(&opus_decoder, NULL, AudioFrameCb, NULL);
137+
138+
ChiakiAudioSink audio_sink;
139+
chiaki_opus_decoder_get_sink(&opus_decoder, &audio_sink);
140+
chiaki_session_set_audio_sink(&session, &audio_sink);
141+
142+
err = chiaki_session_start(&session);
143+
if(err != CHIAKI_ERR_SUCCESS)
144+
{
145+
chiaki_opus_decoder_fini(&opus_decoder);
146+
chiaki_session_fini(&session);
147+
return 2;
148+
}
149+
150+
// For testing purpose. Quit after 10 secs.
151+
sleep(10);
152+
chiaki_opus_decoder_fini(&opus_decoder);
153+
chiaki_session_fini(&session);
154+
return 0;
155+
}

0 commit comments

Comments
 (0)