     {
         event.stopImmediatePropagation();
 
-        // see if we can seek to a position
-        const dur :Number = _player.getDuration();
-        if (isNaN(dur)) {
-            log.debug("Duration is NaN, track click dropped.");
-            return;
-        }
-
-        var perc :Number = event.localX / TRACK_WIDTH;
-        perc = Math.max(0, Math.min(1, perc));
-        log.debug("Seek", "x", event.localX, "perc", perc, "pos", (perc * dur));
-
-        _player.seek(perc * dur);
+        adjustSeek(event.localX);
     }
 
     protected function handleKnobDown (event :MouseEvent) :void
     {
         event.stopImmediatePropagation();
-        // TODO
+
+        _dragging = true;
+        _knob.startDrag(false, new Rectangle(0, TRACK_HEIGHT/2, TRACK_WIDTH, 0));
+        addEventListener(Event.ENTER_FRAME, handleKnobSeekCheck);
+        addEventListener(MouseEvent.MOUSE_UP, handleKnobUp);
     }
 
     protected function handleKnobUp (event :MouseEvent) :void
     {
         event.stopImmediatePropagation();
-        // TODO
+
+        _dragging = false;
+        _knob.stopDrag();
+        removeEventListener(Event.ENTER_FRAME, handleKnobSeekCheck);
+        removeEventListener(MouseEvent.MOUSE_UP, handleKnobUp);
+        handleKnobSeekCheck(null);
+    }
+
+    protected function handleKnobSeekCheck (event :Event) :void
+    {
+        adjustSeek(_knob.x);
     }
 
     protected function handlePlayerState (event :ValueEvent) :void


    protected function handlePlayerPosition (event :ValueEvent) :void
    {
        const pos :Number = Number(event.value);
        _knob.x = (pos / _player.getDuration()) * TRACK_WIDTH;
        if (_knob.parent == null) {

    {
        // TODO.. maybe just redispatch
        log.warning("player error: " + event.value);
    }

    protected function adjustSeek (trackX :Number) :void
    {
        // see if we can seek to a position
        const dur :Number = _player.getDuration();
        if (isNaN(dur)) {
            log.debug("Duration is NaN, not seeking.");
            return;
        }
        if (trackX == _lastKnobX) {
            return;
        }
        _lastKnobX = trackX;
        var perc :Number = trackX / TRACK_WIDTH;
        perc = Math.max(0, Math.min(1, perc));
        log.debug("Seek", "x", trackX, "perc", perc, "pos", (perc * dur));
        _player.seek(perc * dur);
    }

    protected function showHUD (show :Boolean) :void
