Click here to Skip to main content
15,886,774 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everyone,

I recently created a wcf service c# music app for listening and downloading music tracks for consuming data for a front-end Android music streaming app. Everything works good accept the performance of waiting for the music request to finish buffering the entire track from the server to respond back to the client (Android app).

Below here is my code that I'm currently is using to retreive music mp3 files for streaming. Problem is the mp3 files are buffering and I want them to be able to stream instead. Can anyone please help or assist me with showing me a few examples of how I would covert the proxy service method LoadTracksByAlbum(string AlbumID) into stream. Your help will gladely be appreciated.

Note: The TrackUrl property, which is access through the loadTracksbyAlbum object is the only property that relates to the physical mp3 file. The TrackUrl property gets a string path from the database and that reference a folder that contains the mp3 files on the server to be consumed for streaming music on a front-end Android music streaming app.

What I have tried:

I haven't tried anything yet programmically in c#, but I have configured the settings on webconfig file to Transfermode = "Streamed" and the max size and etc. This may ultimately allows me to transfer more data, rather than the fixed 64KB allowed, but it doesn't allow me to utilize the the stream classes like FileStream, BinaryReader and members like CanSeek,CanRead. I don't have the slightess ideal how I would write this stream into my currently service operation LoadTracksByAlbum(string AlbumID). Can anyone please help me out with a few examples. I really appreciate the help.

My data contract:
C#
[DataMember] public string TrackUrl { get; set; }


My service contract:
C#
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, UriTemplate = "LoadTracksByAlbum/{AlbumID}")]
List<LoadAlbumTracks> LoadTracksByAlbum(string AlbumID);


My proxy operation contract method implementation:
C#
public List<LoadAlbumTracks> LoadTracksByAlbum(string AlbumID)
        {
            List<LoadAlbumTracks> loadAlbumTracksList1 = new List<LoadAlbumTracks>();
            MusicDataContext tapesDataContext = new MusicDataContext();
            CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");
            tapesDataContext.CommandTimeout = 0;
            foreach (proc_TracksLoadByAlbumResult loadByAlbumResult in (IEnumerable<proc_TracksLoadByAlbumResult>)tapesDataContext.proc_TracksLoadByAlbum(new int?(Convert.ToInt32(AlbumID))))
            {
                List<LoadAlbumTracks> loadAlbumTracksList2 = loadAlbumTracksList1;
                LoadAlbumTracks loadAlbumTracks1 = new LoadAlbumTracks();
                loadAlbumTracks1.TrackID = loadByAlbumResult.TrackID;
                loadAlbumTracks1.TrackTitle = loadByAlbumResult.TrackTitle;
                loadAlbumTracks1.Artists = loadByAlbumResult.Atists;
                loadAlbumTracks1.DiscJockeyName = loadByAlbumResult.DiscJockeyName;
                loadAlbumTracks1.TrackDescription = loadByAlbumResult.TrackDescription;
                loadAlbumTracks1.TrackUrl = loadByAlbumResult.TrackUrl;
                loadAlbumTracks1.AlbumID = loadByAlbumResult.AlbumID ?? 0;
                loadAlbumTracks1.AlbumCoverPhotoUrl = loadByAlbumResult.AlbumCoverPhotoUrl;
                loadAlbumTracks1.AlbumName = loadByAlbumResult.AlbumName;
                loadAlbumTracks1.TotalStreams = loadByAlbumResult.TotalStreams;
                LoadAlbumTracks loadAlbumTracks2 = loadAlbumTracks1;
                loadAlbumTracks1.DownloadStatus = loadByAlbumResult.DownloadStatus; 
                bool? trackStatus = loadByAlbumResult.TrackStatus;
                int num = trackStatus.HasValue ? (trackStatus.GetValueOrDefault() ? 1 : 0) : 1;
                loadAlbumTracks2.TrackStatus = num != 0;
                loadAlbumTracks1.DjID = loadByAlbumResult.DjID ?? 0;
                loadAlbumTracks1.CreatedBy = loadByAlbumResult.CreatedBy ?? 0;
                loadAlbumTracks1.CreatedOn = !loadByAlbumResult.CreatedOn.HasValue ? "" : loadByAlbumResult.CreatedOn.Value.ToString("d", (IFormatProvider)cultureInfo);
                loadAlbumTracks1.UpdatedBy = loadByAlbumResult.UpdatedBy ?? 0;
                loadAlbumTracks1.UpdatedOn = !loadByAlbumResult.UpdatedOn.HasValue ? "" : loadByAlbumResult.UpdatedOn.Value.ToString("d", (IFormatProvider)cultureInfo);
                LoadAlbumTracks loadAlbumTracks3 = loadAlbumTracks1;
                loadAlbumTracksList2.Add(loadAlbumTracks3);
            }
            return loadAlbumTracksList1;
        }
Posted
Updated 14-Jan-20 9:22am

1 solution

Well, shortly after posting this question, I stubled into finding my own solution. For anyone else who may have a similar question to know how to create a stream in a REST wcf service for a GET request, you can look below and see exactly where I implemeted a MemoryStream instance to wrap my data coming from my List object (Generic) to transfer my data across the wire (network).

C#
[OperationContract]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, UriTemplate = "LoadTracksByAlbum/{AlbumID}")]
        MemoryStream LoadTracksByAlbum(string AlbumID);


C#
public MemoryStream LoadTracksByAlbum(string AlbumID)
        {
            List<LoadAlbumTracks> loadAlbumTracksList1 = new List<LoadAlbumTracks>();
            
            SlappinMixTapesDataContext tapesDataContext = new SlappinMixTapesDataContext();
            CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");
            tapesDataContext.CommandTimeout = 0;
            foreach (proc_TracksLoadByAlbumResult loadByAlbumResult in (IEnumerable<proc_TracksLoadByAlbumResult>)tapesDataContext.proc_TracksLoadByAlbum(new int?(Convert.ToInt32(AlbumID))))
            {
                List<LoadAlbumTracks> loadAlbumTracksList2 = loadAlbumTracksList1;
                LoadAlbumTracks loadAlbumTracks1 = new LoadAlbumTracks();
                loadAlbumTracks1.TrackID = loadByAlbumResult.TrackID;
                loadAlbumTracks1.TrackTitle = loadByAlbumResult.TrackTitle;
                loadAlbumTracks1.Artists = loadByAlbumResult.Atists;
                loadAlbumTracks1.DiscJockeyName = loadByAlbumResult.DiscJockeyName;
                loadAlbumTracks1.TrackDescription = loadByAlbumResult.TrackDescription;
                loadAlbumTracks1.TrackUrl = loadByAlbumResult.TrackUrl;
                loadAlbumTracks1.AlbumID = loadByAlbumResult.AlbumID ?? 0;
                loadAlbumTracks1.AlbumCoverPhotoUrl = loadByAlbumResult.AlbumCoverPhotoUrl;
                loadAlbumTracks1.AlbumName = loadByAlbumResult.AlbumName;
                loadAlbumTracks1.TotalStreams = loadByAlbumResult.TotalStreams;
                LoadAlbumTracks loadAlbumTracks2 = loadAlbumTracks1;
                bool? trackStatus = loadByAlbumResult.TrackStatus;
                int num = trackStatus.HasValue ? (trackStatus.GetValueOrDefault() ? 1 : 0) : 1;
                loadAlbumTracks2.TrackStatus = num != 0;
                loadAlbumTracks1.DjID = loadByAlbumResult.DjID ?? 0;
                loadAlbumTracks1.CreatedBy = loadByAlbumResult.CreatedBy ?? 0;
                loadAlbumTracks1.CreatedOn = !loadByAlbumResult.CreatedOn.HasValue ? "" : loadByAlbumResult.CreatedOn.Value.ToString("d", (IFormatProvider)cultureInfo);
                loadAlbumTracks1.UpdatedBy = loadByAlbumResult.UpdatedBy ?? 0;
                loadAlbumTracks1.UpdatedOn = !loadByAlbumResult.UpdatedOn.HasValue ? "" : loadByAlbumResult.UpdatedOn.Value.ToString("d", (IFormatProvider)cultureInfo);
                LoadAlbumTracks loadAlbumTracks3 = loadAlbumTracks1;
                loadAlbumTracksList2.Add(loadAlbumTracks3);
            }

            byte[] byteArray = new byte[4000];

            // Convert the Object to be serialized and return a JSON string.
            var json1 = new JavaScriptSerializer().Serialize(loadAlbumTracksList1);

            // Convert the string into bytes of array.
            byteArray = Encoding.UTF8.GetBytes(json1);

            MemoryStream stream = new MemoryStream(byteArray);
            stream.ToArray();
            return stream;
        }


And more importantly to complete any type of stream, you need to set your trasport mode in your webconfig file to Streamed (bidirectional) or to the other 2 choices of stream. I hope this is helpful for other people out there who doesn't have the knowledge or any reference to knowing how to implement a stream response back to the client's request.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900