DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report

Displaying Subtitles using Timeline Markers in Windows Phone 7 media applications

Jevgeni Tšaikin user avatar by
Jevgeni Tšaikin
·
Nov. 26, 11 · Interview
Like (0)
Save
Tweet
Share
7.25K Views

Join the DZone community and get the full member experience.

Join For Free

In this tutorial I will show my custom implementation of subtitles using Timeline Markers. Timeline Markers are usually used with SmoothStreamingMediaElement, but in my tutorial I am going to use TimelineMarker and TimelineMarkerCollection classes for my custom Media Player control.

eugenedotnet subtitles for media element using timeline markers

Creating XAML

First step is to create a XAML for our custom Player user control. I have used a very simple version of it that contains only a textbox for displaying subtitle and a MediaElement.

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <MediaElement Grid.Row="0" Height="350" x:Name="meElement" />
    <TextBlock Grid.Row="0" x:Name="tbMarker" Margin="10,0,10,35"
                VerticalAlignment="Bottom" TextWrapping="Wrap" />
</Grid>

Adding properties to codebehind

Next we need to add properties to hold a current timeline marker and a collection of timeline markers for a video. Each timeline marker represents a single subtitle.

private TimelineMarkerCollection Markers { get; set; }
 
private TimelineMarker _currentMarker;
public TimelineMarker CurrentMarker
{
    get
    {
        return _currentMarker;
    }
    set
    {
        _currentMarker = value;
        tbMarker.Text = _currentMarker != null ?
            _currentMarker.Text : string.Empty;
        tbMarker.Visibility = _currentMarker != null ?
            Visibility.Visible : Visibility.Collapsed;
    }
}

Creating Mock Subtitles (Timeline Markers)

During the next step I have created a mock TimelineMarkerCollection representing subtitles for a video content. TimelineMarker is generated every 400 milliseconds and not generated during 5000-10000 millisecond time span.

public static TimelineMarkerCollection CreateMockMarkers(TimeSpan duration)
{
    TimelineMarkerCollection tmc = new TimelineMarkerCollection();
    for (double i = 400; i < duration.TotalMilliseconds; i = i + 400)
    {
        if (i < 5000 || i > 10000)
        {
            tmc.Add(new TimelineMarker()
            {
                Text = string.Format("Some Text at {0}", i),
                Time = TimeSpan.FromMilliseconds(i)
            });
        }
    }
    return tmc;
}

Searching for current marker

Most important step is to find current marker. I want each of my markers to display not longer than 3000 milliseconds (MAXIMUM_MARKER_DURATION variable). Search for a current marker should be accomplished within MediaElement position change event(this event is implemented using DispatcherTimer, also check the next section “Full version of codebehind” to understand the event logic here). Bellow is a code I’ve used for searching.

private void CheckMarkers(double position)
{
    if (Markers != null && Markers.Any())
    {
        CurrentMarker = (from item in Markers
            where item.Time != null
            && item.Time.TotalMilliseconds <= (position + MAXIMUM_MARKER_DURATION)
            && item.Time.TotalMilliseconds >= position
            orderby item.Time descending
            select item).FirstOrDefault();
    }
}

Full version of codebehind

Bellow is a full version of codebehind I’ve used for Player control:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Data;
using System.Globalization;
using System.ComponentModel;
 
namespace EugeneDotnetWPSamples.MediaPlayer
{
    public partial class MediaPlayer : UserControl
    {
 
        DispatcherTimer currentPosition = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(200) };
 
        private double MAXIMUM_MARKER_DURATION = 3000;
 
        private TimelineMarkerCollection Markers { get; set; }
 
        private TimelineMarker _currentMarker;
 
        public TimelineMarker CurrentMarker
        {
            get
            {
                return _currentMarker;
            }
            set
            {
                _currentMarker = value;
                tbMarker.Text = _currentMarker != null ?
                    _currentMarker.Text : string.Empty;
                tbMarker.Visibility = _currentMarker != null ?
                    Visibility.Visible : Visibility.Collapsed;
            }
        }
 
        public MediaPlayer()
        {
            InitializeComponent();
 
            meElement.Source = new Uri(@"http://vnfiles.ign.com/nwvault.ign.com/fms/files/movies/53/CEP1080028433040trailer_low.wmv");
 
            meElement.MediaOpened += (s, e) =>
            {
                Markers = CreateMockMarkers(meElement.NaturalDuration.TimeSpan);
            };
 
            currentPosition.Tick += (s, e) =>
                {
                    CheckMarkers(meElement.Position.TotalMilliseconds);
                };
 
            meElement.CurrentStateChanged += (s, e) =>
            {
                if (meElement.CurrentState == MediaElementState.Playing)
                    currentPosition.Start();
                else
                    currentPosition.Stop();
            };
        }
 
        private void CheckMarkers(double position)
        {
            if (Markers != null && Markers.Any())
            {
                CurrentMarker = (from item in Markers
                                 where item.Time != null
                                 && item.Time.TotalMilliseconds <= (position + MAXIMUM_MARKER_DURATION)
                                 && item.Time.TotalMilliseconds >= position
                                 orderby item.Time descending
                                 select item).FirstOrDefault();
            }
        }
 
        public static TimelineMarkerCollection CreateMockMarkers(TimeSpan duration)
        {
            TimelineMarkerCollection tmc = new TimelineMarkerCollection();
            for (double i = 400; i < duration.TotalMilliseconds; i = i + 400)
            {
                if (i < 5000 || i > 10000)
                {
                    tmc.Add(new TimelineMarker()
                    {
                        Text = string.Format("Some Text at {0}", i),
                        Time = TimeSpan.FromMilliseconds(i)
                    });
                }
            }
            return tmc;
        }
    }
}

Source: http://www.eugenedotnet.com/2011/01/w15-displaying-subtitles-using-timeline-markers/
Timeline Windows Phone Media (communication) application

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 19 Most Common OpenSSL Commands for 2023
  • Java REST API Frameworks
  • File Uploads for the Web (2): Upload Files With JavaScript
  • Use AWS Controllers for Kubernetes To Deploy a Serverless Data Processing Solution With SQS, Lambda, and DynamoDB

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: