0. Create Clip From File Path

let file_path = "path_to_video";
// Add file:/// to the beginning of path
let path_for_gstreamer = format!("file:///{}", file_path);
// Then, we can get clip from the path
let uri_clip = UriClip::new(&path_for_gstreamer)?;

1. Set Video Track Resolution

// The variable type must be i32
let width: i32 = 1920;
let height: i32 = 1080;

let restriction = Caps::builder("video/x-raw")
    .field("width", width)
    .field("height", height)
    .build();

// Create new video track
let video_track = VideoTrack::new();
// Set resolution
video_track.update_restriction_caps(&restriction);

2. Get Resolution From Video Streams

let uri = "file:///path_to_video";
// Discoverer can be found on lib: gstreamer-pbutils
let video = Discoverer::new(ClockTime::from_seconds(60))?;
let video_info = video.discover_uri(uri)?;

let video_stream = video_info.video_streams();

if let Some(stream) = video_stream.into_iter().next() {
    return Ok((stream.width(), stream.height()));
}

3. Adjust Any Clip Volume

// Create clip
let uri_clip = UriClip::new(&path_for_gstreamer)?;
// The volume range: 0.0 ~ 1.0
let volume = 0.1;
// Set volume
let effect = Effect::new(format!("volume volume={}", volume).as_str())?;
// Apply to clip
uri_clip.add(&effect)?;

4. Create TestClip Using Custom Resolution

// Resolution
let width = 1920;
let height = 1080;
// length: 20 seconds
let duration = 20.0;
let asset_test = Asset::request(
    TestClip::static_type(),
    Some(
        format!(
            "framerate=60/1, width={}, height={}, max-duration={}",
            width,
            height,
            duration
        )
        .as_str(),
    ),
)?;
if let Some(asset_test) = asset_test {
    // Add asset to the layer you want
    let clip = layer.add_asset(
        &asset_test,
        ClockTime::from_seconds(0),
        ClockTime::from_seconds(0),
        ClockTime::from_seconds_f64(duration),
        TrackType::VIDEO,
    )?;

    // Clip to TestClip
    let test_clip: Option<&TestClip> = clip.downcast_ref();
    if let Some(test_clip) = test_clip {
        // Then you can call the method of TestClip
        // test_clip.set_vpattern();
    }
}

5. Save Video to Disk

let full_path = format!("file:///path_to_save_video.mp4");

let video_profile = EncodingVideoProfile::builder(&Caps::builder("video/x-h264").build())
    .name("video_profile")
    .build();

let audio_profile = EncodingAudioProfile::builder(&Caps::builder("audio/mpeg").build())
    .name("audio_profile")
    .build();

// container
let caps = Caps::builder("video/quicktime")
    .field("variant", "iso")
    .build();
let profile = EncodingContainerProfile::builder(&caps)
    .name("File Name")
    .description("file description")
    .add_profile(video_profile)
    .add_profile(audio_profile)
    .enabled(true)
    .build();

pipeline.set_render_settings(&full_path, &profile)?;

//  We don't want to play the video. Set pipeline to RENDER mode.
pipeline.set_mode(PipelineFlags::RENDER)?;

// Start rendering video
pipeline.set_state(gstreamer_video::gst::State::Playing)?;

let bus = pipeline.bus();
if let Some(bus) = bus {
    for msg in bus.iter_timed(ClockTime::NONE) {
        match msg.view() {
            MessageView::Eos(..) => break,
            MessageView::Error(err) => {
                error!(
                    "Error from {:?}: {} ({:?})",
                    err.src().map(|s| s.path_string()),
                    err.error(),
                    err.debug()
                );
                break;
            }
            _ => (),
        }
    }

    pipeline.set_state(gstreamer_video::gst::State::Null)?;
}

// Render finish