diff --git a/app/controller.go b/app/controller.go
index baa2f68..9ad0438 100644
--- a/app/controller.go
+++ b/app/controller.go
@@ -39,16 +39,10 @@ func (c *Controller) StartCasting(selected string, mediaURL string) {
 		return
 	}
 
-	err := c.Model.ConnectToDevice(selected)
-	if err != nil {
-		c.LogAndShowError(fmt.Errorf("error connecting to device %v", err))
-		return
-	}
 	go func() {
-		err = c.Model.StartCast(mediaURL)
+		err := c.Model.Cast(selected, mediaURL)
 		if err != nil {
-			c.LogAndShowError(fmt.Errorf("error starting cast %v", err))
-			c.DiscoverDevices()
+			c.LogAndShowError(fmt.Errorf("error starting cast: %v", err))
 			return
 		}
 	}()
@@ -56,6 +50,10 @@ func (c *Controller) StartCasting(selected string, mediaURL string) {
 
 }
 
+func (c *Controller) ShowReconnecting(reconnecting bool) {
+	c.View.PopupReconnecting(reconnecting)
+}
+
 // Note: these are app codes, they are NOT related to fcast opcodes!
 const (
 	ActionPlay        = 0
@@ -78,7 +76,6 @@ func (c *Controller) PlayerAction(action int, args ...float32) {
 }
 
 func (c *Controller) ExitCasting() {
-	c.PlayerAction(ActionStop)
 	c.DiscoverDevices()
 }
 
diff --git a/app/model.go b/app/model.go
index 42bc090..52d6bb3 100644
--- a/app/model.go
+++ b/app/model.go
@@ -7,6 +7,8 @@ import (
 	"io"
 	"math"
 	"net/http"
+	"strings"
+	"time"
 )
 
 type Model struct {
@@ -14,9 +16,11 @@ type Model struct {
 	DiscoveredDevices []fcast.DiscoveredHost
 	Connection        *fcast.Connection
 	EventManager      *fcast.EventManager
+	DeviceName        string
 	Time              float32
 	Length            float32
 	Volume            float32
+	IsReconnecting    bool
 }
 
 func (m *Model) DiscoverDevices() ([]string, error) {
@@ -47,10 +51,29 @@ func (m *Model) ConnectToDevice(name string) error {
 		return err
 	}
 	m.Connection = connection
+	m.DeviceName = name
 	return nil
 }
 
-func (m *Model) StartCast(mediaURL string) error {
+func (m *Model) Cast(selectedDevice, mediaURL string) error {
+	err := m.doCast(selectedDevice, mediaURL)
+	if err != nil {
+		if errors.Is(err, io.EOF) || strings.Contains(err.Error(), "software caused connection abort") {
+			m.Controller.ShowReconnecting(true)
+			time.Sleep(500 * time.Millisecond)
+			return m.Cast(selectedDevice, mediaURL)
+		}
+	}
+	m.Controller.ShowReconnecting(false)
+	return err
+}
+
+func (m *Model) doCast(selectedDevice, mediaURL string) error {
+
+	err := m.ConnectToDevice(selectedDevice)
+	if err != nil {
+		return fmt.Errorf("error connecting to device %v", err)
+	}
 
 	m.EventManager = &fcast.EventManager{}
 
@@ -81,6 +104,13 @@ func (m *Model) StartCast(mediaURL string) error {
 		if err != nil {
 			return err
 		}
+	} else {
+		m.Volume = 1
+	}
+
+	err = m.Connection.SendMessage(&fcast.PingMessage{})
+	if err == nil {
+		m.Controller.ShowReconnecting(false)
 	}
 
 	return m.Connection.ListenForMessages(m.EventManager)
diff --git a/app/view.go b/app/view.go
index e105359..279249e 100644
--- a/app/view.go
+++ b/app/view.go
@@ -18,10 +18,29 @@ type View struct {
 	Controller            *Controller
 	Window                fyne.Window
 	CastingScreenElements CastingScreenElements
+	ReconnectingDialog    *dialog.CustomDialog
 }
 
 func (v *View) PopupError(err error) {
-	dialog.ShowError(err, v.Window)
+	fyne.Do(func() {
+		dialog.ShowError(err, v.Window)
+	})
+}
+
+func (v *View) PopupReconnecting(show bool) {
+	if v.ReconnectingDialog != nil && !show {
+		fyne.DoAndWait(func() {
+			v.ReconnectingDialog.Dismiss()
+			v.ReconnectingDialog = nil
+		})
+		return
+	}
+	if v.ReconnectingDialog == nil && show {
+		v.ReconnectingDialog = dialog.NewCustomWithoutButtons("Reconnecting to stream...", widget.NewProgressBarInfinite(), v.Window)
+		fyne.Do(func() {
+			v.ReconnectingDialog.Show()
+		})
+	}
 }
 
 func NewView(controller *Controller) *View {