diff --git a/src/Lib/Ass/Line.cc b/src/Lib/Ass/Line.cc
index 71eafe81220b7297af8db8067a22496d6e7418c8..27a2c35ed8aaacadba6fe62504d6fdcc4b24faed 100644
--- a/src/Lib/Ass/Line.cc
+++ b/src/Lib/Ass/Line.cc
@@ -129,6 +129,12 @@ Line::getContent() const noexcept
     return content;
 }
 
+QVector<Syl> *
+Line::getContentPtr() noexcept
+{
+    return &content;
+}
+
 bool
 Line::getIsComment() const noexcept
 {
diff --git a/src/Lib/Ass/Line.hh b/src/Lib/Ass/Line.hh
index f24b2e9e48005a850d7fe2c429a5bdc015ff4276..a5fffb0d67e4398337dab433bdf8eddbce7fde28 100644
--- a/src/Lib/Ass/Line.hh
+++ b/src/Lib/Ass/Line.hh
@@ -44,6 +44,8 @@ public:
     StyleWeakPtr getStyle() const noexcept;
     const QVector<Syl> &getContent() const noexcept;
 
+    QVector<Syl> *getContentPtr() noexcept; // FIXME: remove me
+
     quint64 getStart() const noexcept;
     quint64 getEnd() const noexcept;
     QString getContentAsText() const noexcept;
diff --git a/src/Lib/Ass/Syl.cc b/src/Lib/Ass/Syl.cc
index 2c5a3d217a8d5a86ceee4d5ee0de88427a2db40b..91c49b843479888ad66aeb04cd0b76daa3c3d434 100644
--- a/src/Lib/Ass/Syl.cc
+++ b/src/Lib/Ass/Syl.cc
@@ -41,3 +41,9 @@ Syl::getDuration() const noexcept
 {
     return duration;
 }
+
+void
+Syl::setDuration(quint64 x) noexcept
+{
+    duration = x;
+}
diff --git a/src/Lib/Ass/Syl.hh b/src/Lib/Ass/Syl.hh
index e112eef3a10a00c59cfad1eea6fc60b24d1b2e0d..7c603cea14e60d53b041e912a53ade1dd06aa6dd 100644
--- a/src/Lib/Ass/Syl.hh
+++ b/src/Lib/Ass/Syl.hh
@@ -31,6 +31,8 @@ public:
     QString getContent() const noexcept;
     quint64 getDuration() const noexcept;
 
+    void setDuration(quint64) noexcept;
+
 private:
     static quint64 getDurationFromString(const QString &) noexcept;
 };
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
index e43162541975ad10c17183969667708401dfd0c1..26f920c1ff66f86efadcc5353265aa08f80c8a52 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingLine.cc
@@ -4,8 +4,6 @@
 #include <QGraphicsScene>
 
 #include "TimingUtils.hh"
-#include "TimingSyl.hh"
-#include "TimingSeparator.hh"
 
 using namespace Vivy;
 
@@ -14,27 +12,42 @@ TimingLine::TimingLine(Ass::Line *lineptr, QGraphicsItem *parent)
     , line(*lineptr)
 {
     setPos(TimingUtils::posFromMs(int(line.getStart()) * 10), TimingUtils::axisHeight());
-    int currentTime        = 0;
+    originalX       = pos().x();
+    originalY       = pos().y();
+    int currentTime = 0;
+    int endSyl      = 0;
+    int i;
+
+    TimingSeparator *timingSeparatorStart =
+        new TimingSeparator(currentTime, 0, TimingSeparator::SeparatorStyle::Start, this);
+    seps.append(timingSeparatorStart);
+    connect(timingSeparatorStart, &TimingSeparator::positionChanged, this,
+            &TimingLine::timingSeparatorHasChanged);
+
     QVector<Ass::Syl> syls = line.getContent();
-    for (int i = 0; i < syls.size(); ++i) {
-        int endSyl = currentTime + 10 * int(syls.at(i).getDuration());
+    for (i = 0; i < syls.size(); ++i) {
+        endSyl = currentTime + 10 * int(syls.at(i).getDuration());
 
         TimingSyl *timingSyl = new TimingSyl(syls.at(i), currentTime, this);
+        timingSyls.append(timingSyl);
 
         // TODO: Here create the TimingSeparator and connect
-        TimingSeparator *timingSeparatorStart =
-            new TimingSeparator(currentTime,
-                                i != 0 ? TimingSeparator::SeparatorStyle::Middle
-                                       : TimingSeparator::SeparatorStyle::Start,
-                                this);
-        TimingSeparator *timingSeparatorEnd =
-            new TimingSeparator(i != syls.size() - 1 ? endSyl : int(10 * line.getDuration()),
-                                i != syls.size() - 1 ? TimingSeparator::SeparatorStyle::Middle
-                                                     : TimingSeparator::SeparatorStyle::End,
-                                this);
+        if (i != 0) {
+            TimingSeparator *timingSeparator =
+                new TimingSeparator(currentTime, i, TimingSeparator::SeparatorStyle::Middle, this);
+            seps.append(timingSeparator);
+            connect(timingSeparator, &TimingSeparator::positionChanged, this,
+                    &TimingLine::timingSeparatorHasChanged);
+        }
 
         currentTime = endSyl;
     }
+
+    TimingSeparator *timingSeparatorEnd =
+        new TimingSeparator(currentTime, i, TimingSeparator::SeparatorStyle::End, this);
+    seps.append(timingSeparatorEnd);
+    connect(timingSeparatorEnd, &TimingSeparator::positionChanged, this,
+            &TimingLine::timingSeparatorHasChanged);
 }
 
 QRectF
@@ -52,3 +65,84 @@ TimingLine::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWi
                              TimingUtils::audioHeight()),
                       QColor(0, 255, 255, 50));
 }
+
+void
+TimingLine::timingSeparatorHasChanged(int sylIndex, qreal x)
+{
+}
+
+qreal
+TimingLine::requestMove(int sepIndex, qreal x)
+{
+    QRectF sceneRect        = mapRectFromScene(scene()->sceneRect());
+    QVector<Ass::Syl> *syls = line.getContentPtr();
+
+    qreal ret = x;
+    qreal mini, maxi;
+
+    if (sepIndex <= 0) {
+        prepareGeometryChange();
+
+        mini = sceneRect.left();
+        maxi = sepIndex < syls->size() - 1 ? timingSyls[sepIndex + 1]->pos().x()
+                                           : TimingUtils::posFromMs(int(line.getDuration()) * 10);
+
+        if (ret < mini)
+            ret = mini;
+        if (ret > maxi)
+            ret = maxi;
+
+        quint64 dur1 = quint64(TimingUtils::msFromPos(int(seps[1]->pos().x() - ret)) / 10);
+        (*syls)[0].setDuration(dur1);
+        timingSyls[0]->setLen(dur1);
+        setPos(originalX + ret, originalY);
+        line.setStart(line.getStart() +
+                      quint64(TimingUtils::msFromPos(int(originalX) + int(ret) / 10)));
+    }
+
+    else if (sepIndex >= syls->size()) {
+        prepareGeometryChange();
+
+        mini = timingSyls[sepIndex - 1]->pos().x();
+        maxi = sceneRect.right();
+
+        if (ret < mini)
+            ret = mini;
+        if (ret > maxi)
+            ret = maxi;
+
+        quint64 dur2 =
+            quint64(TimingUtils::msFromPos(int(ret - timingSyls[sepIndex - 1]->pos().x())) / 10);
+        (*syls)[sepIndex - 1].setDuration(dur2);
+        timingSyls[sepIndex - 1]->setLen(dur2);
+        line.setEnd(line.getStart() + quint64(TimingUtils::msFromPos(int(ret)) / 10));
+    }
+
+    else {
+        mini = timingSyls[sepIndex - 1]->pos().x();
+        maxi = sepIndex < syls->size() - 1 ? timingSyls[sepIndex + 1]->pos().x()
+                                           : TimingUtils::posFromMs(int(line.getDuration() * 10));
+
+        if (ret < mini)
+            ret = mini;
+        if (ret > maxi)
+            ret = maxi;
+
+        quint64 sumDur = (*syls)[sepIndex].getDuration() + (*syls)[sepIndex - 1].getDuration();
+        quint64 dur1   = quint64(
+              TimingUtils::msFromPos(int(ret) - int(timingSyls[sepIndex - 1]->pos().x())) / 10);
+        if (dur1 > sumDur) {
+            dur1 = sumDur;
+        }
+        quint64 dur2 = sumDur - dur1;
+
+        (*syls)[sepIndex - 1].setDuration(dur1);
+        (*syls)[sepIndex].setDuration(dur2);
+
+        timingSyls[sepIndex - 1]->setLen(dur1);
+        timingSyls[sepIndex]->setPos(ret, 0);
+        timingSyls[sepIndex]->setLen(dur2);
+    }
+
+    return ret;
+}
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh b/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
index ea7c7f86f82168e20cd2e003889339dd919815eb..a611631624eba593bc6d4901e6f2e6a20184c8b7 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingLine.hh
@@ -3,6 +3,8 @@
 #include <QGraphicsObject>
 
 #include "../../../Lib/Ass/Ass.hh"
+#include "TimingSeparator.hh"
+#include "TimingSyl.hh"
 
 namespace Vivy
 {
@@ -16,6 +18,16 @@ public:
 
 private:
     Ass::Line line;
+    QVector<TimingSeparator *> seps;
+    QVector<TimingSyl *> timingSyls;
+    int originalX;
+    int originalY;
+
+public:
+    qreal requestMove(int, qreal);
+
+public slots:
+    void timingSeparatorHasChanged(int, qreal);
 };
 
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.cc b/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.cc
index e8811d4dedb3b587a7c013d204446d3aaa676d4e..cc0ac33f8ba902520187b962970f5e7632ac7ce4 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.cc
@@ -2,17 +2,25 @@
 
 #include <QPainter>
 #include <QGraphicsScene>
+#include <QDrag>
 
 #include "TimingUtils.hh"
+#include "TimingLine.hh"
 
 using namespace Vivy;
 
-TimingSeparator::TimingSeparator(int time, SeparatorStyle style_, QGraphicsItem *parent)
+TimingSeparator::TimingSeparator(int time, int index, SeparatorStyle style_, TimingLine *parent)
     : QGraphicsObject(parent)
     , style(style_)
+    , sepIndex(index)
+    , parentTimingLine(parent)
 {
     setPos(TimingUtils::posFromMs(time), 0);
 
+    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges);
+    setAcceptHoverEvents(true);
+    setCursor(Qt::PointingHandCursor);
+
     switch (style) {
     case SeparatorStyle::Start: pen = QPen(QColor(0, 0, 255)); break;
     case SeparatorStyle::Middle: pen = QPen(QColor(180, 0, 180)); break;
@@ -54,3 +62,19 @@ TimingSeparator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
         break;
     }
 }
+
+QVariant
+TimingSeparator::itemChange(GraphicsItemChange change, const QVariant &value) noexcept
+{
+    if (change == ItemPositionChange) {
+        qreal destination = value.toPointF().x();
+        destination       = parentTimingLine->requestMove(sepIndex, destination);
+
+        if (style == SeparatorStyle::Start)
+            destination = 0;
+
+        emit positionChanged(sepIndex, destination);
+        return QPointF(destination, 0);
+    }
+    return QGraphicsObject::itemChange(change, value);
+}
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.hh b/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.hh
index 61fdd95bc16e3b1d738a652bdd97dbc5140dbfe1..4d90df97102f750b3419ea1ebe5b93e595b2b7ea 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.hh
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingSeparator.hh
@@ -1,17 +1,19 @@
 #pragma once
 
 #include <QGraphicsObject>
+#include <QGraphicsSceneDragDropEvent>
 
 namespace Vivy
 {
+class TimingLine;
+
 class TimingSeparator final : public QGraphicsObject {
     Q_OBJECT
 public:
     enum class SeparatorStyle { Start, Middle, End };
 
 public:
-    explicit TimingSeparator(int, SeparatorStyle style = SeparatorStyle::Middle,
-                             QGraphicsItem *parent = nullptr);
+    explicit TimingSeparator(int, int, SeparatorStyle, TimingLine *);
 
     QRectF boundingRect() const override;
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
@@ -20,6 +22,14 @@ private:
     SeparatorStyle style;
     int widthPaw = 5;
     QPen pen;
+    int sepIndex;
+    TimingLine *parentTimingLine;
+
+signals:
+    void positionChanged(int, qreal);
+
+protected:
+    QVariant itemChange(GraphicsItemChange change, const QVariant &value) noexcept override;
 };
 
 }
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingSyl.cc b/src/UI/DocumentViews/AudioVisualizer/TimingSyl.cc
index 548324fa910c9570cadcaac178faf2142f416a49..291804cb62835b2ae501941ce449a35566e86ba8 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingSyl.cc
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingSyl.cc
@@ -26,3 +26,10 @@ TimingSyl::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
 {
     painter->drawText(boundingRect(), Qt::AlignCenter, syl.getContent());
 }
+
+void
+TimingSyl::setLen(quint64 len)
+{
+    prepareGeometryChange();
+    syl.setDuration(len);
+}
diff --git a/src/UI/DocumentViews/AudioVisualizer/TimingSyl.hh b/src/UI/DocumentViews/AudioVisualizer/TimingSyl.hh
index fcf74aea60089e621e2b2347f52f286b5ad8213c..26a46ae56d4f6aa0c4e9dcbba9f2c5893f4bd9e3 100644
--- a/src/UI/DocumentViews/AudioVisualizer/TimingSyl.hh
+++ b/src/UI/DocumentViews/AudioVisualizer/TimingSyl.hh
@@ -16,6 +16,9 @@ public:
 
 private:
     Ass::Syl syl;
+
+public:
+    void setLen(quint64 len);
 };
 
 }