xref: /haiku/src/bin/media_client/MediaPlay.cpp (revision 5e7964b0a929555415798dea3373db9ac4611caa)
1 /*
2  * Copyright 2017, Dario Casalinuovo. All rights reserved.
3  * Copyright 2005, Marcus Overhagen, marcus@overhagen.de. All rights reserved.
4  * Copyright 2005, Jérôme Duval. All rights reserved.
5  * Distributed under the terms of the MIT License.
6  */
7 
8 #include "MediaPlay.h"
9 
10 #include <Entry.h>
11 #include <MediaFile.h>
12 #include <MediaTrack.h>
13 #include <OS.h>
14 #include <SoundPlayer.h>
15 #include <Url.h>
16 
17 #include <stdio.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <signal.h>
21 
22 thread_id reader = -1;
23 sem_id finished = -1;
24 BMediaTrack* playTrack;
25 media_format playFormat;
26 BSoundPlayer* player = 0;
27 volatile bool interrupt = false;
28 
29 
30 void
31 play_buffer(void *cookie, void * buffer, size_t size, const media_raw_audio_format & format)
32 {
33 	int64 frames = 0;
34 
35 	// Use your feeling, Obi-Wan, and find him you will.
36 	playTrack->ReadFrames(buffer, &frames);
37 
38 	if (frames <=0) {
39 		player->SetHasData(false);
40 		release_sem(finished);
41 	}
42 }
43 
44 
45 void
46 keyb_int(int)
47 {
48 	// Are you threatening me, Master Jedi?
49 	interrupt = true;
50 	release_sem(finished);
51 }
52 
53 
54 int media_play(const char* uri)
55 {
56 	BUrl url;
57 	entry_ref ref;
58 	BMediaFile* playFile;
59 
60 	if (get_ref_for_path(uri, &ref) != B_OK) {
61 		url.SetUrlString(uri);
62 		if (url.IsValid()) {
63 			playFile = new BMediaFile(url);
64 		} else
65 			return 2;
66 	} else
67 		playFile = new BMediaFile(&ref);
68 
69 	if (playFile->InitCheck() != B_OK) {
70 		delete playFile;
71 		return 2;
72 	}
73 
74 	for (int i = 0; i < playFile->CountTracks(); i++) {
75 		BMediaTrack* track = playFile->TrackAt(i);
76 		playFormat.type = B_MEDIA_RAW_AUDIO;
77 		if ((track->DecodedFormat(&playFormat) == B_OK)
78 				&& (playFormat.type == B_MEDIA_RAW_AUDIO)) {
79 			playTrack = track;
80 			break;
81 		}
82 		if (track)
83 			playFile->ReleaseTrack(track);
84 	}
85 
86 	// Good relations with the Wookiees, I have.
87 	signal(SIGINT, keyb_int);
88 
89 	finished = create_sem(0, "finish wait");
90 
91 	printf("Playing file...\n");
92 
93 	// Execute Plan 66!
94 	player = new BSoundPlayer(&playFormat.u.raw_audio, "playfile", play_buffer);
95 	player->SetVolume(1.0f);
96 
97 	// Join me, Padmé and together we can rule this galaxy.
98 	player->SetHasData(true);
99 	player->Start();
100 
101 	acquire_sem(finished);
102 
103 	if (interrupt == true) {
104 		// Once more, the Sith will rule the galaxy.
105 		printf("Interrupted\n");
106 		player->Stop();
107 		kill_thread(reader);
108 	}
109 
110 	printf("Playback finished.\n");
111 
112 	delete player;
113 	delete playFile;
114 }
115