What is the L-shaped items overlaying?
The main idea of L-shaped items displaying is to transform the video output rectangle (squeeze it) and display some overlay items on a freed space.
The L-shaped items overlay is very useful for advertising, "see next" section displaying and other service purposes.
There are 2 ways to make the L-shape overlay: use a CG object (available with MPlatform and MFormats) or use MMixer object (available inMPlatform).
Which way to choose?
It depends on your requirements.
L-shape with CG
+ Consumes less system resources.
+ Easier to use.
+ Can be applied to almost any other object.
- Underlying property applies to the whole CG object, so if you need to keep some CG items on top of the video, you'll have o use multiple CG plugins.
- Unable to make complex scenes like MMixer object.
L-shape with MMixer
+ Supports complex MMixer scenes.
+ Can have multiple CG objects applied to any source or output.
- Consumes much more system resources than the CG option.
- A bit harder to use in case of usage CG for underlying stream configuration.
Displaying the L-Shape items with MMixer object.
The idea behind the making of L-shape with MMixer object is to make 2 MMixer layers one under another. The upper one will playback the content and the lower one will contain underlying L-shape composition. After that, you can switch the views to make a smooth transition from the original view to the L-shaped one and backward.
The concept description
1 . Add the content stream to MMixer object and add it's representation to the scene. It can be a file, a playlist or any other required stream source. This is your main stream that will be transformed during the L-shape displaying.
2. Add the underlying stream. This one will contain your L-shape content, for example, "see next" section.
The L-shape content stream can have any preferred configuration according to your requirements:
- Common MMixer stream. In this case, the L-shape content is represented by a stream source. It can be a picture, a movie, a playlist, etc.
- Transparent MMixer stream, with a CG object on it. In this case, the L-shape content is represented by a CG overlay items that will be placed on the stream.
- A bunch of MMixer streams in a composition.
In my demo code I'll use a transparent MMixer stream with a CG object on top of it.
3. Configure your scene. Make sure that your L-shape stream is in a right position and the correct areas will be visible after the main content stream squeeze. Make sure that the main content stream on top of the L-shape one.
4. Add 2 views of your scene. The first one is the current scene state when the base stream is displayed on full mixer area. The second one is L-shaped state when the base stream is reduced to display the L-shape of underlying video.
This views will let MMixer know how to transform the base video item to display the underlying one.
5. Invoke required views to perform a smooth transition from the original view to L-shaped one and backward.
A code sample
// 1. Add the base stream source video MItem myMainSourceStream; m_objMixer.StreamsAdd("myMainSourceStream", null, @"d:/temp/!SharkTale.avi", "", out myMainSourceStream, 0.0); // Add the base video to the scene // I pick the 0 element - it's a foreground when youe scene is empty // If you have a complex scene thhen I would recommed you to enumerate elements // and choose the required one MElement rootElement; m_objMixer.ElementsGetByIndex(0, out rootElement); // Add my main video element to the foreground MElement mainVideoElement; ((IMElements)rootElement).ElementsAdd("", "video", "stream_id=myMainSourceStream h=1 w=1 show=1", out mainVideoElement, 0.0); // 2. Add the underlying source stream to MMixer MItem myUnderlyingSourceItem; m_objMixer.StreamsAdd("myUnderlyingSourceItem", null, "transparent", "", out myUnderlyingSourceItem, 0.0); // Add a CG item to this stream. // Note that CG is applied to this particular input stream only, not the whole MMixer output m_objCharGen = new MLCHARGENLib.CoMLCharGen(); (myUnderlyingSourceItem as IMPlugins).PluginsAdd(m_objCharGen, 0); // Add the L-shape content to the CG and show it string cGItemId = ""; m_objCharGen.AddNewItem(@"D:\Medialooks\Sample Videos\L-Shape CG\bunny2.jpg", -0.3, 0, 1, 1, ref cGItemId); m_objCharGen.ShowItem(cGItemId, 1, 0); // Add the underlying video to the scene // I pick the 0 element - it's a foreground when your scene is empty // If you have a complex scene then I would recommend you to enumerate elements // and choose the required one MElement rootElement1; m_objMixer.ElementsGetByIndex(0, out rootElement1); // Add my underlying video element to the foreground MElement underlyingVideoElement; ((IMElements)rootElement1).ElementsAdd("", "video", "stream_id=myUnderlyingSourceItem h=1 w=1 show=1", out underlyingVideoElement, 0.0); // 3. Reorder elements - put the main on top of the underlying underlyingVideoElement.ElementReorder(0); mainVideoElement.ElementReorder(10); // 4. Add views for the L-shape transition performing MElement rootElement2; m_objMixer.ElementsGetByIndex(1, out rootElement2); // Add the main view. // Here I have a main video on a full screen MElement view1; ((IMElements)rootElement2).ElementsAdd("", "view", "id=base_view", out view1, 0.0); MElement tempElement1; ((IMElements)view1).ElementsAdd("", "video", "target_id='foreground::video_000' h=1 w=1 x=0 y=0", out tempElement1, 0.0); // Add the L-shaped view. // Here my main video size is reduced by 70% and located in top-right position. // Note that I do not specify the X any Y position in a second view. // I just reduce it's size and set the position to "top-right" to avoid the manual position calculation. MElement view2; ((IMElements)rootElement2).ElementsAdd("", "view", "id=l_shaped_view", out view2, 0.0); MElement tempElement2; ((IMElements)view2).ElementsAdd("", "video", "target_id='foreground::video_000' h=0.7 w=0.7 pos='top-right' ", out tempElement2, 0.0); // 5. Invoke the views to make a transition form the base view to L-shaped one and backward. // ... some code here ... // Make a smooth transition to L-shaped view within 2 seconds view2.ElementInvoke("select", "true", 2); // ... some code here ... // Make a smooth transition to base view within 2 seconds view1.ElementInvoke("", "true", 1);
Once you're done you can save your MMIxer configuration to the XML file and load it further for L-shape performing.
Note: When you save the XML configuration, it saves the content of MMixer object only. So if you perform the L-shape displaying with the CG on top of the transparent stream, like I did in this example, your CG content would not be saved. Sou you need to save the CG configuration separately and add it as a plugin to transparent MMixer stream manually.
Try loading your configuration and making L-shape with Mixer sample application