# FFmpeg Transcoding Command Parameters in Bilistream: Complete Guide

> Explore FFmpeg transcoding command parameters in bilistream. Learn how to use -re -vcodec copy -acodec aac -f flv for HLS to RTMP relay. Get the complete guide.

- Repository: [InitCool/bilistream](https://github.com/limitcool/bilistream)
- Tags: deep-dive
- Published: 2026-03-06

---

**Bilistream assembles an FFmpeg command with specific transcoding parameters—`-re`, `-vcodec copy`, `-acodec aac`, and `-f flv`—to relay HLS streams to RTMP endpoints via the `ffmpeg` helper function defined in [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs).**

Bilistream is an open-source Rust application that rebroadcasts live streams from HLS (M3U8) sources to RTMP endpoints like Bilibili. Understanding the **FFmpeg transcoding command parameters** is essential for customizing stream behavior, debugging connectivity issues, or extending the tool's functionality.

## Core Implementation in [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs)

The FFmpeg invocation logic resides in the `ffmpeg` helper function defined at lines 27-48 of [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs). This function constructs and executes the external `ffmpeg` binary with a predetermined argument set optimized for live stream relay.

### Function Signature and Inputs

The Rust function accepts four parameters that map directly to command-line components:

```rust
pub fn ffmpeg(
    rtmp_url: String,      // Base RTMP endpoint (e.g., rtmp://live-push.bilibili.com/live/)
    rtmp_key: String,      // Stream key appended to the endpoint
    m3u8_url: String,      // Source HLS playlist URL
    ffmpeg_proxy: Option<String>, // Optional HTTP proxy for ffmpeg traffic
)

```

## FFmpeg Transcoding Command Parameters Explained

Bilistream constructs the FFmpeg command by conditionally adding arguments based on the provided inputs. Each parameter serves a specific technical purpose in the transcoding pipeline.

### Input and Timing Controls

- **`-re`** (line 38): Reads the input at native frame rate, ensuring real-time streaming that does not consume the source faster than it produces frames.
- **`-i <m3u8_url>`** (lines 39-40): Specifies the HLS playlist URL as the input source for the transcoding process.

### Video and Audio Codecs

- **`-vcodec copy`** (lines 41-42): Performs **stream copy** for video, avoiding CPU-intensive re-encoding while preserving original quality and reducing latency.
- **`-acodec aac`** (lines 43-44): Forces audio transcoding to AAC format, which is required for compatibility with Bilibili and most other RTMP ingestion endpoints.

### Output Formatting and Destination

- **`-f flv`** (lines 45-46): Forces the output container format to FLV, the standard container protocol for RTMP streams.
- **`<rtmp_url><rtmp_key>`** (lines 28-30): Concatenates the base URL and stream key to form the complete destination address pushed to the server.

### Optional Networking Parameters

- **`-http_proxy <proxy>`** (lines 34-37): Added only when `ffmpeg_proxy` is `Some`, routing HTTP traffic through the specified proxy to access geo-restricted HLS sources.

## Complete Command Structure

The assembled command follows this exact pattern:

```bash
ffmpeg [-http_proxy <proxy>] -re -i <m3u8_url> \
       -vcodec copy -acodec aac -f flv <rtmp_url><rtmp_key>

```

When no proxy is configured, the `-http_proxy` argument is omitted entirely.

## Practical Usage Examples

### Calling the Function from Rust

To invoke the transcoding pipeline programmatically within the bilistream codebase:

```rust
use crate::ffmpeg;

let rtmp_url = "rtmp://live-push.bilibili.com/live/".to_string();
let rtmp_key = "live_123456_789012".to_string();
let m3u8_url = "https://source-cdn.example.com/stream.m3u8".to_string();
let proxy = Some("http://127.0.0.1:3128".to_string());

ffmpeg(rtmp_url, rtmp_key, m3u8_url, proxy);

```

### Executing FFmpeg Directly in Shell

For debugging or manual streaming, execute FFmpeg with the equivalent parameters:

```bash
ffmpeg -http_proxy http://127.0.0.1:3128 \
       -re -i https://source-cdn.example.com/stream.m3u8 \
       -vcodec copy -acodec aac -f flv \
       rtmp://live-push.bilibili.com/live/live_123456_789012

```

## Configuration and Source Files

The transcoding behavior is governed by settings defined across the repository:

- **[`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs)**: Contains the `ffmpeg` function implementation (lines 27-48) and the runtime logic that spawns the process.
- **[`src/config.rs`](https://github.com/limitcool/bilistream/blob/main/src/config.rs)**: Defines the `Config` struct including the optional `ffmpeg_proxy` field used to populate the proxy parameter.
- **[`Cargo.toml`](https://github.com/limitcool/bilistream/blob/main/Cargo.toml)**: Declares Rust dependencies like `tokio` that manage the asynchronous workflow surrounding the FFmpeg process.

## Summary

- Bilistream uses a hardcoded FFmpeg parameter set in [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs) to transcode HLS streams to RTMP format with minimal overhead.
- The command utilizes **stream copy** (`-vcodec copy`) for video to minimize CPU usage while enforcing AAC audio encoding (`-acodec aac`) for protocol compliance.
- An optional `ffmpeg_proxy` parameter injects `-http_proxy` for accessing restricted sources without modifying system-wide network settings.
- All parameters are assembled via the `ffmpeg` function at lines 27-48 of the main source file according to the bilistream source code.

## Frequently Asked Questions

### Why does Bilistream use `-vcodec copy` instead of re-encoding video?

The `-vcodec copy` parameter performs stream copying without decoding and re-encoding video frames. This approach eliminates CPU overhead and latency, making it ideal for relaying streams where the source format is already compatible with RTMP endpoints.

### How do I add custom FFmpeg parameters to the bilistream command?

Currently, the `ffmpeg` function in [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs) uses a fixed set of arguments. To customize parameters, you must modify the source code between lines 34-46 of [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs), adding or removing `.arg()` calls on the `Command` builder before recompiling the project.

### What happens if I don't provide the `ffmpeg_proxy` parameter?

If `ffmpeg_proxy` is `None`, the conditional block at lines 34-37 is skipped, and the FFmpeg command executes without the `-http_proxy` argument. The stream connects directly to the HLS source using the default network interface.

### Is the audio always transcoded to AAC?

Yes, according to the implementation at lines 43-44 of [`src/main.rs`](https://github.com/limitcool/bilistream/blob/main/src/main.rs), the `-acodec aac` flag is always present in the command. This ensures compatibility with Bilibili's RTMP ingestion requirements, which mandate AAC audio format.