Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support LL-HLS #41

Open
wants to merge 10 commits into
base: ll-hls
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
implement llhls chunking
Phineas committed Jul 23, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 42cf7398571e5e6c6a2c970d414050b56a86bee1
2 changes: 1 addition & 1 deletion application/xiu/Cargo.toml
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ failure = "0.1.1"

rtmp = "0.0.14"#{path = "../../protocol/rtmp/"}#"0.0.4"
httpflv = "0.0.7"#{path = "../../protocol/httpflv/"}
hls = "0.0.10"#{path = "../../protocol/hls/"}
hls = {path = "../../protocol/hls/"}

# rtmp = {path = "../../protocol/rtmp/"}#"0.0.4"
# httpflv = {path = "../../protocol/httpflv/"}
29 changes: 28 additions & 1 deletion protocol/hls/src/flv2hls.rs
Original file line number Diff line number Diff line change
@@ -18,13 +18,16 @@ pub struct Flv2HlsRemuxer {
ts_muxer: TsMuxer,

last_ts_dts: i64,
last_partial_ts_dts: i64,
last_ts_pts: i64,

last_dts: i64,
last_pts: i64,

duration: i64,
partial_seg_duration: i64,
need_new_segment: bool,
need_new_partial_segment: bool,

video_pid: u16,
audio_pid: u16,
@@ -33,7 +36,12 @@ pub struct Flv2HlsRemuxer {
}

impl Flv2HlsRemuxer {
pub fn new(duration: i64, app_name: String, stream_name: String) -> Self {
pub fn new(
duration: i64,
partial_seg_duration: i64,
app_name: String,
stream_name: String,
) -> Self {
let mut ts_muxer = TsMuxer::new();
let audio_pid = ts_muxer
.add_stream(epsi_stream_type::PSI_STREAM_AAC, BytesMut::new())
@@ -51,13 +59,16 @@ impl Flv2HlsRemuxer {
ts_muxer,

last_ts_dts: 0,
last_partial_ts_dts: 0,
last_ts_pts: 0,

last_dts: 0,
last_pts: 0,

duration,
partial_seg_duration,
need_new_segment: false,
need_new_partial_segment: false,

video_pid,
audio_pid,
@@ -114,6 +125,7 @@ impl Flv2HlsRemuxer {
flv_demux_data: &FlvDemuxerData,
) -> Result<(), MediaError> {
self.need_new_segment = false;
self.need_new_partial_segment = false;

let pid: u16;
let pts: i64;
@@ -136,6 +148,8 @@ impl Flv2HlsRemuxer {
flags = MPEG_FLAG_IDR_FRAME;
if dts - self.last_ts_dts >= self.duration * 1000 {
self.need_new_segment = true;
} else if self.last_ts_dts >= self.partial_seg_duration {
self.need_new_partial_segment = true;
}
}
}
@@ -152,6 +166,19 @@ impl Flv2HlsRemuxer {
_ => return Ok(()),
}

if self.need_new_partial_segment {
println!("nnps?: {}", self.need_new_partial_segment)
}

if self.need_new_partial_segment {
let d = self.ts_muxer.get_data();

self.m3u8_handler
.add_partial_segment(dts - self.last_partial_ts_dts, d)?;

self.last_partial_ts_dts = dts;
}

if self.need_new_segment {
let mut discontinuity: bool = false;
if dts > self.last_ts_dts + 15 * 1000 {
2 changes: 1 addition & 1 deletion protocol/hls/src/flv_data_receiver.rs
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ impl FlvDataReceiver {

data_consumer,
event_producer,
media_processor: Flv2HlsRemuxer::new(duration, app_name, stream_name),
media_processor: Flv2HlsRemuxer::new(duration, 500, app_name, stream_name),
subscriber_id,
}
}
16 changes: 15 additions & 1 deletion protocol/hls/src/m3u8.rs
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ pub struct M3u8 {
live_ts_count: usize,

segments: VecDeque<Segment>,
partial_segments: VecDeque<Segment>,
is_header_generated: bool,

m3u8_header: String,
@@ -72,6 +73,7 @@ impl M3u8 {
is_live: true,
live_ts_count,
segments: VecDeque::new(),
partial_segments: VecDeque::new(),
is_header_generated: false,
m3u8_folder,
m3u8_header: String::new(),
@@ -97,13 +99,25 @@ impl M3u8 {

self.duration = std::cmp::max(duration, self.duration);

let (ts_name, ts_path) = self.ts_handler.write(ts_data)?;
let (ts_name, ts_path) = self.ts_handler.write(ts_data, false)?;
let segment = Segment::new(duration, discontinuity, ts_name, ts_path, is_eof);
self.segments.push_back(segment);

Ok(())
}

pub fn add_partial_segment(
&mut self,
duration: i64,
ts_data: BytesMut,
) -> Result<(), MediaError> {
let cur_seg = self.segments.len();
let cur_partial_seg = self.partial_segments.len();

let (ts_name, ts_path) = self.ts_handler.write(ts_data, true)?;
Ok(())
}

pub fn clear(&mut self) -> Result<(), MediaError> {
//clear ts
for segment in &self.segments {
10 changes: 9 additions & 1 deletion protocol/hls/src/server.rs
Original file line number Diff line number Diff line change
@@ -37,12 +37,14 @@ async fn handle_connection(req: Request<Body>) -> Result<Response<Body>> {
let (left, _) = path.split_at(ts_index);

let rv: Vec<_> = left.split("/").collect();
println!("{:?}", rv);

let app_name = String::from(rv[1]);
let stream_name = String::from(rv[2]);
let ts_name = String::from(rv[3]);

file_path = format!("./{}/{}/{}.ts", app_name, stream_name, ts_name);
println!("{}", file_path)
}
}

@@ -63,7 +65,13 @@ async fn simple_file_send(filename: &str) -> Result<Response<Body>> {
if let Ok(file) = File::open(filename).await {
let stream = FramedRead::new(file, BytesCodec::new());
let body = Body::wrap_stream(stream);
return Ok(Response::new(body));
let r = Response::builder()
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "*")
.header("Access-Control-Allow-Headers", "*")
.body(body);
return Ok(r.unwrap());
}

Ok(not_found())
5 changes: 3 additions & 2 deletions protocol/hls/src/test_flv2hls.rs
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ mod tests {
#[allow(dead_code)]
fn test_flv2hls() -> Result<(), MediaError> {
let mut file =
File::open("/Users/zexu/github/xiu/protocol/hls/src/xgplayer_demo.flv").unwrap();
File::open("/Users/phin/misc/xiu/protocol/hls/src/xgplayer_demo.flv").unwrap();
let mut contents = Vec::new();

file.read_to_end(&mut contents)?;
@@ -67,7 +67,8 @@ mod tests {
demuxer.read_flv_header()?;

let start = Instant::now();
let mut media_demuxer = Flv2HlsRemuxer::new(5, String::from("live"), String::from("test"));
let mut media_demuxer =
Flv2HlsRemuxer::new(5, 200, String::from("live"), String::from("test"));

loop {
let data_ = demuxer.read_flv_tag();
18 changes: 15 additions & 3 deletions protocol/hls/src/ts.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use {

pub struct Ts {
ts_number: u32,
pts_number: u32,
folder_name: String,
}

@@ -16,13 +17,24 @@ impl Ts {

Self {
ts_number: 0,
pts_number: 0,
folder_name,
}
}
pub fn write(&mut self, data: BytesMut) -> Result<(String, String), MediaError> {
let ts_file_name = format!("{}.ts", self.ts_number);
pub fn write(&mut self, data: BytesMut, partial: bool) -> Result<(String, String), MediaError> {
let ts_file_name = format!(
"{}{}.ts",
self.ts_number,
if partial {
self.pts_number += 1;
format!("{}.", self.pts_number)
} else {
self.pts_number = 0;
self.ts_number += 1;
String::from("")
},
);
let ts_file_path = format!("{}/{}", self.folder_name, ts_file_name);
self.ts_number += 1;

let mut ts_file_handler = File::create(ts_file_path.clone())?;
ts_file_handler.write_all(&data[..])?;