Player Synch

Mar 14, 2013 at 3:33 PM
Edited Mar 15, 2013 at 7:23 AM
Hello,

We're trying to implement a multi-camera application where user can choose between cameras they want to watch and we're having some problems keeping them synchronized (especially when users play back and use DVR controls to seek video).

We've followed the instructions in the Picture-in-Picture document here , but we can't make it work as described. As far as we can tell the heuristics plugin doesn't affect anything. We've tried adjusting the master/slave settings in the heuristics.xml file without any impact on the player synchronization.

Both players start playback when we press the play button, but then depending on the network environment, perhaps one player will buffer and the other player will not and it's very likely that within a few minutes the players are significantly out of synch with one another.

Beyond that, seeking using the main control strip appears to have no impact on the pip player.

So, two specific questions:
  1. Should this keep the players in synch with one another during normal playback?
    A> If so, any idea what we're doing wrong (complete code is below)?
    B> If not, how can we synch two or more players?
  2. Should this also work when seeking or using DVR controls?
    A> If so, any idea what we're doing wrong?
    B> If not, can you point us in the right direction of how to achieve this?
Many thanks!

Here is the complete code.

MainPage.xaml
<UserControl x:Class="MyTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:smf="http://schemas.microsoft.com/smf/2010/xaml/player"
             xmlns:smf_media="http://schemas.microsoft.com/smf/2010/xaml/media"
             xmlns:smf_converters="http://schemas.microsoft.com/smf/2010/xaml/converters" mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition  />
            <RowDefinition  />            
        </Grid.RowDefinitions>

        <smf:SMFPlayer Name="main" EnableSync="True" Grid.Row="0" >
            <smf:SMFPlayer.HeuristicsPluginRequiredMetadata>
                <smf_converters:MetadataItem Key="SupportsMaterSlaveMode" Value="True" />
            </smf:SMFPlayer.HeuristicsPluginRequiredMetadata>
            <smf:SMFPlayer.Playlist>
                <smf_media:PlaylistItem DeliveryMethod="AdaptiveStreaming" MediaSource="http://ecn.channel9.msdn.com/o9/content/smf/smoothcontent/elephantsdream/Elephants_Dream_1024-h264-st-aac.ism/manifest"></smf_media:PlaylistItem>
            </smf:SMFPlayer.Playlist>
        </smf:SMFPlayer>

        
        <smf:SMFPlayer Name="pip"  IsControlStripVisible="True" Grid.Row="1" >
            <smf:SMFPlayer.HeuristicsPluginRequiredMetadata>
                <smf_converters:MetadataItem Key="SupportsMaterSlaveMode" Value="True" />                
            </smf:SMFPlayer.HeuristicsPluginRequiredMetadata>
            <smf:SMFPlayer.Playlist>
                <smf_media:PlaylistItem DeliveryMethod="AdaptiveStreaming" MediaSource="http://video3.smoothhd.com.edgesuite.net/ondemand/Big%20Buck%20Bunny%20Adaptive.ism/Manifest"></smf_media:PlaylistItem>
            </smf:SMFPlayer.Playlist>
        </smf:SMFPlayer>

    </Grid>
</UserControl>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using Microsoft.SilverlightMediaFramework.Plugins;
using Microsoft.SilverlightMediaFramework.Plugins.Primitives;

namespace MyTest
{
    public partial class MainPage : UserControl
    {
        const string trackKeyName = "cameraAngle";
        const string trackValueFormat = "camera{0}";

        public MainPage()
        {
            InitializeComponent();

            main.HeuristicsPriority = 0;
            pip.HeuristicsPriority = -1;
            main.MediaOpened += main_MediaOpened;
            pip.MediaOpened += pip_MediaOpened;
        }


        void main_MediaOpened(object sender, EventArgs e)
        {
            var player = (IPlayer)sender;
            SelectVideoTracks(2, player.ActiveMediaPlugin as IAdaptiveMediaPlugin);
        }

        void pip_MediaOpened(object sender, EventArgs e)
        {
            var player = (IPlayer)sender;
            SelectVideoTracks(4, player.ActiveMediaPlugin as IAdaptiveMediaPlugin);
        }

        void SelectVideoTracks(int trackNumber, IAdaptiveMediaPlugin ActiveAdaptiveMediaPlugin)
        {
            if (ActiveAdaptiveMediaPlugin == null)
                return;
            ISegment currentSegment = ActiveAdaptiveMediaPlugin.CurrentSegment;
            if (currentSegment == null || currentSegment.AvailableStreams == null)
                return;
            IMediaStream videoStream = currentSegment.AvailableStreams.Where(s => s.Type == StreamType.Video).FirstOrDefault();
            if (videoStream == null)
                return;
            var trackName = string.Format(trackValueFormat, trackNumber);
            var pair = new KeyValuePair<string, string>(trackKeyName, trackName);
            var tracks = videoStream.AvailableTracks.Where(t => t.CustomAttributes.Contains(pair));
            if (tracks.Any())
            {
                videoStream.SetSelectedTracks(tracks);
            }
            else
            {
                // Select all tracks and let the SSME choose the default track.
                videoStream.SetSelectedTracks(videoStream.AvailableTracks);
            }
        }
    }
}
Jul 9, 2013 at 12:24 AM
Did you have any progress with that?
Sep 13, 2013 at 1:47 PM
Yes, Synch worked for me.

There were a very stupid typo, I've done.

<smf_converters:MetadataItem Key="SupportsMaterSlaveMode" Value="True" />

SupportsMaterSlaveMode = Should be SupportsMasterSlaveMode


Please let me know your problem.


Dev