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