IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

"Slider" Lecteur multimedia


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 79
    Par défaut "Slider" Lecteur multimedia
    Bonjour,

    je dois faire un lecteur multimedia dans un cours à l'école. J'ai un petit problème avec ma barre de temps qui suit la vidéo. J'utilise un dispatcher timer pour synchroniser ma petite barre avec ma vidéo, cependant étant donné que je change la valeur de la barre, la fonction _ValueChanged est appelé et mon vidéo a donc de petit "Lag". Voici mon code pour mieux me comprendre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private void dispatcherTimer_Tick(object sender, EventArgs e)
            {
                timeSlider.Value = mediaElement1.Position.TotalMilliseconds;            
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    private void timeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
            {
                int sliderValue = (int)timeSlider.Value;
                TimeSpan ts = new TimeSpan(0, 0, 0, 0, sliderValue);
                mediaElement1.Position = ts;            
            }
    Donc lorsque mon timer "Tick" il synchronise la barre avec la vidéo. Par la suite il appelle timeSlider_ValueChanged parce que ma valeur à changé et il synchronise par la suite la vidéo avec la barre. Donc parfois cela crée de petit "Lag".

    Quelqu'un aurait des suggestions pour régler ce conflit?

    Edit: Je travaille avec Visual Studio 2010

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    forcément, tu change la valeur du slide, et tu dis que la valeur du slide change tu modifies la vidéo
    ce qu'il te faut en fait c'est "quand l'utilisateur change la valeur du slide" et pas ton code

    tu peux te créer un booléen qui permet de savoir si la modification vient de toi

    timer_tick
    {
    modifier slide.Value
    set bool à true
    }

    slide_changed
    {
    si bool => set bool à false et sortir
    modifier vidéo}


    cependant ca reste moyen, ca suppose qu'il ne se passe rien entre les 2 méthodes


    tu peux aussi utiliser l'évènement click plutot que valuechanged ; mais là aussi y a un défaut, ca ne gère plus le clavier en cas de focus sur le slider
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    J'aurais fais à peu près comme Pol63, mais avec une petite différence : j'aurais plutôt remis le flag à false au niveau du timer (mais bon, en pratique ça doit pas changer grand chose...)



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
            bool _changingSliderFromTimer;
     
            private void dispatcherTimer_Tick(object sender, EventArgs e)
            {
                _changingSliderFromTimer = true;
                timeSlider.Value = mediaElement1.Position.TotalMilliseconds;            
                _changingSliderFromTimer = false;
            }
     
            private void timeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
            {
                if (_changingSliderFromTimer)
                    return;
                int sliderValue = (int)timeSlider.Value;
                TimeSpan ts = new TimeSpan(0, 0, 0, 0, sliderValue);
                mediaElement1.Position = ts;            
            }

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    c'est vrai que l'event doit être déclenché pendant le changement de valeur (s'il est mis sur la pile c'est moins drôle ^^)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut mediaelement et maj position du slider
    bonjour joce21
    Pourquoi passer par un timer et un dispatcherTimer alors que l'api WPF dispose dispose du MediaTimeLine et d'une horloge ad hoc utilisable par un MediaElement
    De plus le "clock" du MediaElement dispose d'un controller pour l'interactivite.

    Comme l'illustre le bout de code suivant:
    code xaml du WinForm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    <Window x:Class="WpfMediaPlayerCSharp.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <DockPanel>
            <Grid DockPanel.Dock="Bottom">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button 
                    Grid.Column="2"
                    Content="Stop"
                    Click="Stop_Click" />
                <Button 
                    Grid.Column="3"
                    Content="Play"
                    Click="Play_Click" />
                <ToggleButton 
                    Grid.Column="4"
                    Content="Mute"
                    IsChecked="{Binding ElementName=mediaElement,
                    Path=IsMuted}" />
                <Slider 
                    Grid.Column="5"
                    Minimum="0"
                    Maximum="1"
                    Value="{Binding ElementName=mediaElement, Path=Volume}"/>
            </Grid>
            <Slider 
                x:Name="progressSlider"
                DockPanel.Dock="Bottom"
                Minimum="0"
                LargeChange="1000"
                PreviewMouseLeftButtonDown="progressSlider_MouseDown"
                PreviewMouseLeftButtonUp="progressSlider_MouseUp"/>
            <MediaElement 
                x:Name="mediaElement"
                DockPanel.Dock="Top"
                Source="Resources\Bear.wmv"
                LoadedBehavior="Manual"
                MediaOpened="mediaElement_MediaOpened"
                MediaEnded="mediaElement_MediaEnded"/>
        </DockPanel>
    </Window>
    code behind du winform:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    //1-Affecter l'horloge de la chronologie du MediaTimeLine au MediaElement
    //2-S'abonner à l'evenement clock.CurrentTimeInvalidated de l'horloge
    // pour mettre à jour la position du bouton slider
    //3-Horloge dispose du controller qui permet de :
    //- demarrer ,suspendre,reprendre interactivement  la lectur du MediaMediaElement
     
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    namespace WpfMediaPlayerCSharp
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            private bool _userMovingSlider ;
            public Window1()
            {
                InitializeComponent();
            }
     
            private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
            {
                //A l'ouverture du media fixer  valeur max bouton slider  
                this.progressSlider.Maximum = 
                    this.mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
            }
            private void Play_Click(object sender, RoutedEventArgs e)
            {
     
                MediaClock clock=this.mediaElement.Clock;
                //un media est en cours de lecture
                if (clock !=null) 
                {
                    if (clock.IsPaused) 
                    {
                        clock.Controller.Resume();
                    }
                    else
                    {
                        clock.Controller.Pause();
                    }
                }
                else //sinon
                {
                    //aucun fichier charge =>return
                    if (this.mediaElement == null) return;
     
                    //sinon nouveau media => initialiser creer un MediaTimeline 
                    //=> affecter son horloge au MediaElement
                    //=> s'abonner à event horloge
                    MediaTimeline timeline = new MediaTimeline(this.mediaElement.Source);
                    clock = timeline.CreateClock();
     
                    clock.CurrentTimeInvalidated += new EventHandler(Clock_CurrentTimeInvalidated);
                    this.mediaElement.Clock = clock;
                }
            }
            private void Stop_Click(object sender, RoutedEventArgs e)
            {
                //mettre horloge à null
                this.mediaElement.Clock = null;
            }
            private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                //mettre horloge à null
                this.mediaElement.Clock = null;
            }
            private void Clock_CurrentTimeInvalidated(object sender, EventArgs e)
            {
                //si horloge null(aucun media en cours)
                //ou user deplace bouton slider =>return
     
                if (this.mediaElement.Clock == null || _userMovingSlider) return;
                //sinon mise à jour position du slider
                this.progressSlider.Value = 
                this.mediaElement.Clock.CurrentTime.Value.TotalMilliseconds;
     
            }
     
            private void progressSlider_MouseDown(object sender, MouseButtonEventArgs e)
            {
                //user deplace bouton slider
                _userMovingSlider = true;
            }
     
            private void progressSlider_MouseUp(object sender, MouseButtonEventArgs e)
            { 
     
                MediaClock clock=this.mediaElement.Clock;
                //user a deplace puis relache bouton slider
                //mais horloge non nulle(un media en cours de lecture)
                //avancer horloger  à la position du slider
                if (clock !=null)
                    {  
                      TimeSpan m_offset= TimeSpan.FromMilliseconds(this.progressSlider.Value);
                      clock.Controller.Seek(m_offset, TimeSeekOrigin.BeginTime);
                    }
                //prepare prochaine interaction user
                _userMovingSlider = false;
            }
     
     
        }
    }
    bon code..........

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    code behind du winform:
    Les habitudes ont la vie dure

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 79
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    bonjour joce21
    Pourquoi passer par un timer et un dispatcherTimer alors que l'api WPF dispose dispose du MediaTimeLine et d'une horloge ad hoc utilisable par un MediaElement
    De plus le "clock" du MediaElement dispose d'un controller pour l'interactivite.

    Comme l'illustre le bout de code suivant:
    code xaml du WinForm
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    <Window x:Class="WpfMediaPlayerCSharp.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <DockPanel>
            <Grid DockPanel.Dock="Bottom">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button 
                    Grid.Column="2"
                    Content="Stop"
                    Click="Stop_Click" />
                <Button 
                    Grid.Column="3"
                    Content="Play"
                    Click="Play_Click" />
                <ToggleButton 
                    Grid.Column="4"
                    Content="Mute"
                    IsChecked="{Binding ElementName=mediaElement,
                    Path=IsMuted}" />
                <Slider 
                    Grid.Column="5"
                    Minimum="0"
                    Maximum="1"
                    Value="{Binding ElementName=mediaElement, Path=Volume}"/>
            </Grid>
            <Slider 
                x:Name="progressSlider"
                DockPanel.Dock="Bottom"
                Minimum="0"
                LargeChange="1000"
                PreviewMouseLeftButtonDown="progressSlider_MouseDown"
                PreviewMouseLeftButtonUp="progressSlider_MouseUp"/>
            <MediaElement 
                x:Name="mediaElement"
                DockPanel.Dock="Top"
                Source="Resources\Bear.wmv"
                LoadedBehavior="Manual"
                MediaOpened="mediaElement_MediaOpened"
                MediaEnded="mediaElement_MediaEnded"/>
        </DockPanel>
    </Window>
    code behind du winform:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    //1-Affecter l'horloge de la chronologie du MediaTimeLine au MediaElement
    //2-S'abonner à l'evenement clock.CurrentTimeInvalidated de l'horloge
    // pour mettre à jour la position du bouton slider
    //3-Horloge dispose du controller qui permet de :
    //- demarrer ,suspendre,reprendre interactivement  la lectur du MediaMediaElement
     
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    namespace WpfMediaPlayerCSharp
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            private bool _userMovingSlider ;
            public Window1()
            {
                InitializeComponent();
            }
     
            private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
            {
                //A l'ouverture du media fixer  valeur max bouton slider  
                this.progressSlider.Maximum = 
                    this.mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
            }
            private void Play_Click(object sender, RoutedEventArgs e)
            {
     
                MediaClock clock=this.mediaElement.Clock;
                //un media est en cours de lecture
                if (clock !=null) 
                {
                    if (clock.IsPaused) 
                    {
                        clock.Controller.Resume();
                    }
                    else
                    {
                        clock.Controller.Pause();
                    }
                }
                else //sinon
                {
                    //aucun fichier charge =>return
                    if (this.mediaElement == null) return;
     
                    //sinon nouveau media => initialiser creer un MediaTimeline 
                    //=> affecter son horloge au MediaElement
                    //=> s'abonner à event horloge
                    MediaTimeline timeline = new MediaTimeline(this.mediaElement.Source);
                    clock = timeline.CreateClock();
     
                    clock.CurrentTimeInvalidated += new EventHandler(Clock_CurrentTimeInvalidated);
                    this.mediaElement.Clock = clock;
                }
            }
            private void Stop_Click(object sender, RoutedEventArgs e)
            {
                //mettre horloge à null
                this.mediaElement.Clock = null;
            }
            private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                //mettre horloge à null
                this.mediaElement.Clock = null;
            }
            private void Clock_CurrentTimeInvalidated(object sender, EventArgs e)
            {
                //si horloge null(aucun media en cours)
                //ou user deplace bouton slider =>return
     
                if (this.mediaElement.Clock == null || _userMovingSlider) return;
                //sinon mise à jour position du slider
                this.progressSlider.Value = 
                this.mediaElement.Clock.CurrentTime.Value.TotalMilliseconds;
     
            }
     
            private void progressSlider_MouseDown(object sender, MouseButtonEventArgs e)
            {
                //user deplace bouton slider
                _userMovingSlider = true;
            }
     
            private void progressSlider_MouseUp(object sender, MouseButtonEventArgs e)
            { 
     
                MediaClock clock=this.mediaElement.Clock;
                //user a deplace puis relache bouton slider
                //mais horloge non nulle(un media en cours de lecture)
                //avancer horloger  à la position du slider
                if (clock !=null)
                    {  
                      TimeSpan m_offset= TimeSpan.FromMilliseconds(this.progressSlider.Value);
                      clock.Controller.Seek(m_offset, TimeSeekOrigin.BeginTime);
                    }
                //prepare prochaine interaction user
                _userMovingSlider = false;
            }
     
     
        }
    }
    bon code..........
    Merci beaucoup, je n'avais pas connaissance de ce clock en question.

    Cependant, je ne comprends la différence entre PreviewMouseDown et MouseDown. Quelqu'un pourrait m'éclairer?

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo