iTunes COM PlayerPositionMS value update interval

56 Views Asked by At

I'm working on two C# winforms and WPF applications that utilize the iTunes COM and have noticed some peculiar behavior accessing the PlayerPositionMS property, which is the player's position in milliseconds. The precision of the PlayerPositionMS value is dependent on whether or not the iTunes application has focus or not. The goal for my 2 apps would be to update the player position with the most accuracy. Any assistance would be appreciated.

Below is some sample code to illustrate my point. This is a winforms application with a single label and timer. The timer interval is the default 100 milliseconds, and the tick method updates the label text with the PlayerPositionMS property value. When iTunes has focus the label is updated as expected. But when the winforms application, or anything else, has focus the label is updated roughly every second. The behavior is the same on winforms and WPF.

  • iTunes version: 12.9.0.167
  • iTunesLib version: 1.13

Form snip:

enter image description here

Form code:

namespace Test
{
    partial class Form_Test
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.label_Position = new System.Windows.Forms.Label();
            this.timer_Test = new System.Windows.Forms.Timer(this.components);
            this.SuspendLayout();
            // 
            // label_Position
            // 
            this.label_Position.AutoSize = true;
            this.label_Position.Location = new System.Drawing.Point(12, 9);
            this.label_Position.Name = "label_Position";
            this.label_Position.Size = new System.Drawing.Size(16, 13);
            this.label_Position.TabIndex = 0;
            this.label_Position.Text = "---";
            // 
            // timer_Test
            // 
            this.timer_Test.Enabled = true;
            this.timer_Test.Tick += new System.EventHandler(this.UpdateLabel);
            // 
            // Form_Test
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(205, 33);
            this.Controls.Add(this.label_Position);
            this.Name = "Form_Test";
            this.Text = "Test Form";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label_Position;
        private System.Windows.Forms.Timer timer_Test;
    }
}

Code behind:

using iTunesLib;
using System;
using System.Windows.Forms;

namespace Test
{
    public partial class Form_Test : Form
    {
        private static iTunesApp _itunes = new iTunesLib.iTunesApp();

        public Form_Test()
        {
            InitializeComponent();
        }

        private void UpdateLabel(object sender, EventArgs e)
        {
            if (_itunes.CurrentTrack != null && _itunes.PlayerState == ITPlayerState.ITPlayerStatePlaying)
                label_Position.Text = _itunes.PlayerPositionMS.ToString();
        }
    }
}
1

There are 1 best solutions below

0
On

Calling the Resume method before accessing the PlayerPositionMS property seems to work to resolve this:

private void UpdateLabel(object sender, EventArgs e)
{
    if (_itunes.CurrentTrack != null && _itunes.PlayerState == ITPlayerState.ITPlayerStatePlaying)
    {
        _itunes.Resume();
        label_Position.Text = _itunes.PlayerPositionMS.ToString();
    }
}