Index: src/apps/mediaplayer/Controller.cpp
===================================================================
--- src/apps/mediaplayer/Controller.cpp	(revision 41122)
+++ src/apps/mediaplayer/Controller.cpp	(working copy)
@@ -30,11 +30,14 @@
 #include <Autolock.h>
 #include <Bitmap.h>
 #include <Debug.h>
+#include <Directory.h>
+#include <MediaFile.h>
 #include <Path.h>
 #include <Window.h> // for debugging only
 
 #include "AutoDeleter.h"
 #include "ControllerView.h"
+#include "FilePlaylistItem.h"
 #include "MainApp.h"
 #include "PlaybackState.h"
 #include "Settings.h"
@@ -42,6 +45,7 @@
 
 // suppliers
 #include "AudioTrackSupplier.h"
+#include "MediaFileTrackSupplier.h"
 #include "MediaTrackAudioSupplier.h"
 #include "MediaTrackVideoSupplier.h"
 #include "ProxyAudioSupplier.h"
@@ -288,6 +292,8 @@
 
 	fTrackSupplier = trackSupplier;
 
+	_BindExtraMedia();
+
 	SelectAudioTrack(0);
 	SelectVideoTrack(0);
 
@@ -1179,7 +1185,73 @@
 }
 
 
+// If fTrackSupplier has only either audio or video, _BindExtraMedia() searches
+// alternative video or audio and addes it to fTrackSupplier as a extra media.
 void
+Controller::_BindExtraMedia()
+{
+	// If fTrackSupplier has already had both audio and video, there is no need
+	// to search alternative media.
+	if ( fTrackSupplier->CountAudioTracks() == 0 && fTrackSupplier->CountVideoTracks() == 0
+			|| fTrackSupplier->CountAudioTracks() > 0 && fTrackSupplier->CountVideoTracks() > 0 )
+			return;
+
+	// Currently, _BindExtraMedia() searches alternative media only from files.
+	FilePlaylistItem*	fileItem = dynamic_cast<FilePlaylistItem*>(fItem.Get());
+	if ( fileItem == NULL )
+		return;
+
+	// For example, if the media file is foo.mp3, _BindExtraMedia() searches foo.avi
+	// and addes video track of foo.avi as a extra media.
+	BPath	mediaFilePath(&fileItem->Ref());
+	BString	mediaFilePathString = mediaFilePath.Path();
+	BPath	dirPath;
+	mediaFilePath.GetParent(&dirPath);
+	BDirectory	dir(dirPath.Path());
+	if ( dir.InitCheck() != B_OK )
+		return;
+	
+	BEntry	entry;
+	BString	entryPathString;
+	while ( dir.GetNextEntry(&entry, true) == B_OK ) {
+		if ( !entry.IsFile() )
+			continue;
+		entryPathString = BPath(&entry).Path();
+		if ( entryPathString != mediaFilePathString
+				&& _GetExceptExtension(entryPathString) == _GetExceptExtension(mediaFilePathString) ) {
+			if ( _BindExtraMedia(entryPathString) == B_OK )
+				return;
+		}
+	}
+}
+
+
+status_t
+Controller::_BindExtraMedia(const BString& path)
+{
+	// Currently, _BindExtraMedia() searches alternative media only from files.
+	MediaFileTrackSupplier*	supplier = dynamic_cast<MediaFileTrackSupplier*>(fTrackSupplier);
+	if ( supplier == NULL )
+		return B_ERROR;
+		
+	entry_ref	ref;
+	get_ref_for_path(path.String(), &ref);
+	BMediaFile*	mediaFile = new BMediaFile(&ref);
+	return supplier->AddExtraMediaTracks(mediaFile);
+}
+
+
+BString
+Controller::_GetExceptExtension(const BString& path) const
+{
+	int32	periodPos = path.FindLast('.');
+	if ( periodPos <= path.FindLast('/') )
+		return path;
+	return BString(path.String(), periodPos);
+}
+
+
+void
 Controller::NotifyPlayModeChanged(int32 mode) const
 {
 	uint32 state = _PlaybackState(mode);
Index: src/apps/mediaplayer/Controller.h
===================================================================
--- src/apps/mediaplayer/Controller.h	(revision 41122)
+++ src/apps/mediaplayer/Controller.h	(working copy)
@@ -175,6 +175,11 @@
 			void				_NotifyVolumeChanged(float volume) const;
 			void				_NotifyMutedChanged(bool muted) const;
 
+	// extra media binding
+			void				_BindExtraMedia();
+			status_t			_BindExtraMedia(const BString& path);
+			BString				_GetExceptExtension(const BString& path) const;
+
 	// overridden from PlaybackManager so that we
 	// can use our own Listener mechanism
 	virtual	void				NotifyPlayModeChanged(int32 mode) const;
Index: src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp
===================================================================
--- src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp	(revision 41122)
+++ src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp	(working copy)
@@ -22,52 +22,17 @@
 MediaFileTrackSupplier::MediaFileTrackSupplier(BMediaFile* mediaFile)
 	:
 	TrackSupplier(),
-	fMediaFile(mediaFile)
+	fMediaFile(mediaFile),
+	fExtraMediaFile(NULL)
 {
-	if (fMediaFile->InitCheck() != B_OK)
-		return;
-	int trackCount = fMediaFile->CountTracks();
-	if (trackCount <= 0)
-		return;
-
-	for (int i = 0; i < trackCount; i++) {
-		BMediaTrack* track = fMediaFile->TrackAt(i);
-		media_format format;
-		status_t status = track->EncodedFormat(&format);
-		if (status != B_OK) {
-			fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for "
-				"track index %d, error: %s\n", i, strerror(status));
-			fMediaFile->ReleaseTrack(track);
-			continue;
-		}
-
-		if (track->Duration() <= 0) {
-			fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "
-				"has no duration\n", i);
-		}
-
-		if (format.IsAudio()) {
-			if (!fAudioTracks.AddItem(track)) {
-				fMediaFile->ReleaseTrack(track);
-				return;
-			}
-		} else if (format.IsVideo()) {
-			if (!fVideoTracks.AddItem(track)) {
-				fMediaFile->ReleaseTrack(track);
-				return;
-			}
-		} else {
-			printf("MediaFileTrackSupplier: track index %d has unknown "
-				"type\n", i);
-			fMediaFile->ReleaseTrack(track);
-		}
-	}
+	_AddTracks(fMediaFile, true, true);
 }
 
 
 MediaFileTrackSupplier::~MediaFileTrackSupplier()
 {
 	delete fMediaFile;
+	delete fExtraMediaFile;
 		// BMediaFile destructor will call ReleaseAllTracks()
  	for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--)
  		delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i));
@@ -189,3 +154,63 @@
 	return fSubTitleTracks.AddItem(subTitles);
 }
 
+
+status_t
+MediaFileTrackSupplier::AddExtraMediaTracks(BMediaFile* mediaFile)
+{
+	delete fExtraMediaFile;
+	fExtraMediaFile = mediaFile;
+	if ( _AddTracks(mediaFile, CountAudioTracks() == 0, CountVideoTracks() == 0) != B_OK )
+		return B_ERROR;
+	return B_OK;
+}
+
+
+status_t
+MediaFileTrackSupplier::_AddTracks(BMediaFile* mediaFile, bool audio, bool video)
+{
+	if (mediaFile->InitCheck() != B_OK)
+		return B_ERROR;
+	int trackCount = mediaFile->CountTracks();
+	if (trackCount <= 0)
+		return B_ERROR;
+
+	status_t	funcStatus = B_ERROR;
+	for (int i = 0; i < trackCount; i++) {
+		BMediaTrack* track = mediaFile->TrackAt(i);
+		media_format format;
+		status_t status = track->EncodedFormat(&format);
+		if (status != B_OK) {
+			fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for "
+				"track index %d, error: %s\n", i, strerror(status));
+			mediaFile->ReleaseTrack(track);
+			continue;
+		}
+
+		if (track->Duration() <= 0) {
+			fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "
+				"has no duration\n", i);
+		}
+
+		if (format.IsAudio()) {
+			if (audio && fAudioTracks.AddItem(track)) {
+				funcStatus = B_OK;
+			} else {
+				mediaFile->ReleaseTrack(track);
+			}
+		} else if (format.IsVideo()) {
+			if (video && fVideoTracks.AddItem(track)) {
+				funcStatus = B_OK;
+			} else {
+				mediaFile->ReleaseTrack(track);
+			}
+		} else {
+			printf("MediaFileTrackSupplier: track index %d has unknown "
+				"type\n", i);
+			mediaFile->ReleaseTrack(track);
+		}
+	}
+	return funcStatus;
+}
+
+
Index: src/apps/mediaplayer/supplier/MediaFileTrackSupplier.h
===================================================================
--- src/apps/mediaplayer/supplier/MediaFileTrackSupplier.h	(revision 41122)
+++ src/apps/mediaplayer/supplier/MediaFileTrackSupplier.h	(working copy)
@@ -41,8 +41,14 @@
 
 			bool				AddSubTitles(SubTitles* subTitles);
 
+			status_t			AddExtraMediaTracks(BMediaFile* mediaFile);
+
 private:
+			status_t			_AddTracks(BMediaFile* mediaFile, bool audio, bool video);
+
+private:
 			BMediaFile*			fMediaFile;
+			BMediaFile*			fExtraMediaFile;
 			BList				fAudioTracks;
 			BList				fVideoTracks;
 			BList				fSubTitleTracks;
