c# - 音频文件的独立存储不使用单独的点击事件

标签 c# windows-phone-8 audio-streaming

我开始意识到将所有这些音频文件打包到 xap 中只是一个坏主意,因为它现在已经增长到大约 60 mb。我不想再将我的音频文件与应用程序打包在一起,而是想使用 URL 并在用户按下声音按钮时将它们加载到独立存储中。我不确定如何使用我的应用程序执行此操作,因为我的按钮没有单独编码。它们会自动从 View 模型加载到 LongListSelectors 中。并根据单击哪个播放(data.filepath)。 下面,我尝试使用独立存储但收到错误。

更新的 mainpage.cs:

public partial class MainPage : PhoneApplicationPage
{
    public string FilePath { get; set; }
    WebClient _webClient;
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Set the data context of the listbox control to the sample data
        DataContext = App.ViewModel;

        //webclient download
        _webClient = new WebClient();
        _webClient.OpenReadCompleted += (s1, e1) =>
        {
            if (e1.Error == null)
            {
                try
                {
                    string fileName = FilePath.
                            Substring(FilePath.LastIndexOf("/") + 1).Trim();
                    bool isSpaceAvailable = 
                        IsSpaceIsAvailable(e1.Result.Length);

                    if (isSpaceAvailable)
                    {
                        // Save mp3 to Isolated Storage
                        using (var isfs = new IsolatedStorageFileStream(
                                fileName, FileMode.CreateNew,
                                IsolatedStorageFile.GetUserStoreForApplication()))
                        {
                            long fileLen = e1.Result.Length;
                            byte[] b = new byte[fileLen];
                            e1.Result.Read(b, 0, b.Length);
                            isfs.Write(b, 0, b.Length);
                            isfs.Flush();
                        }
                    }
                    else
                    {
                        MessageBox.Show("Not enough to save space available to download mp3.");
                    }

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show(e1.Error.Message);
            }
        };
     }

    // Check to make sure there are enough space available on the phone
    // in order to save the image that we are downloading on to the phone
    private bool IsSpaceIsAvailable(long spaceReq)
    {
        using (var store = IsolatedStorageFile.GetUserStoreForApplication())
        {

            long spaceAvail = store.AvailableFreeSpace;
            if (spaceReq > spaceAvail)
            {
                return false;
            }
            return true;
        }
     }
        // Sample code to localize the ApplicationBar




    // Load data for the ViewModel Items
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
            App.ViewModel.LoadData();
        }
    }

    private void LongListSelector_SelectionChanged(
        object sender, SelectionChangedEventArgs e)
    {
        LongListSelector selector = sender as LongListSelector;

        // verifying our sender is actually a LongListSelector
        if (selector == null)
            return;

        SoundData data = selector.SelectedItem as SoundData;

        // verifying our sender is actually SoundData
        if (data == null)
            return;


        if (File.Exists(data.FilePath))
        {
            AudioPlayer.Source = new Uri(
                data.FilePath,  
                UriKind.RelativeOrAbsolute);
        }
        else
        {
            using (var storageFolder =
                IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var stream = new IsolatedStorageFileStream(
                        data.FilePath, FileMode.Open, storageFolder))
                {
                    AudioPlayer.SetSource(stream);
                }
            }
        }

        selector.SelectedItem = null;

这是我的 SoundModel 模型的一部分。我留下了一个例子,说明它现在是如何使用本地存储进行设置的。另一个是 id 喜欢使用 url 的方式。

private SoundGroup CreateGamesGroup()
        {
            SoundGroup data = new SoundGroup();

            data.Title = "Games";
            string basePath = "assets/audio/Games/";

            data.Items.Add(new SoundData
            {
                Title = "Gauntlet Exit",
                FilePath = basePath + "GauntletExit.mp3",
                Groups = "VideoGames"
            });                  

            data.Items.Add(new SoundData
            {
                Title = "Gauntlet Exit",
                FilePath = 
                    "http://k007.kiwi6.com/hotlink/23lenhzr3h/GauntletExit.mp3",
                Groups="VideoGames"
            });

由于 Mainpage.cs 引用了 SoundData 模型,因此我也将在此处添加:

 public class SoundData : ViewModelBase
{
    public string Title { get; set; }
    public string FilePath { get; set; }
    public string Items { get; set; }
    public string Groups { get; set; }


    public RelayCommand<string> SaveSoundAsRingtone { get; set; }


    private void ExecuteSaveSoundAsRingtone(string soundPath)
    {
        App.Current.RootVisual.Dispatcher.BeginInvoke(() =>
        {
            SaveRingtoneTask task = new SaveRingtoneTask();
            task.Source = new Uri("appdata:/" + this.FilePath);
            task.DisplayName = this.Title;
            task.Show();
        }
            );
    }   

    public SoundData()
    {
        SaveSoundAsRingtone = 
            new RelayCommand<string>(ExecuteSaveSoundAsRingtone);
    }

目前 url 无法正常工作,正如我预期的那样。我收到这些错误:

在 mscorlib.ni.dll 中发生类型为“System.IO.IsolatedStorage.IsolatedStorageException”的第一次机会异常 mscorlib.ni.dll 中出现“System.IO.IsolatedStorage.IsolatedStorageException”类型的异常,但未在用户代码中处理 附加信息:IsolatedStorageFileStream 上不允许的操作。

最佳答案

不确定这是否是您问题的根本原因,但您需要对 XAP 中包含的文件使用 appdata:/,否则使用 isostore:/

当您通过暴露的属性将项目绑定(bind)到 LongListSelector 时,您可以将命令分配给您的项目并处理 View 模型中的“点击”。

假设您的 VM 中有以下内容:

public ObservableCollection<SoundData> AudioFiles { get; set; }
public ICommand PlayCommand { get; set; }

然后相关的 XAML 将类似于:

<phone:LongListSelector
        x:Name="AudioFilesList" 
        ItemsSource="{Binding AudioFiles}"
        SelectedItem="{Binding SoundData}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Tap">
                <command:EventToCommand 
                    Command="{Binding PlayCommand}" 
                    CommandParameter="{Binding Path=SelectedItem, 
                        ElementName=AudioFilesList}" 
                    PassEventArgsToCommand="False" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <phone:LongListSelector.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Border BorderThickness="2" 
                            BorderBrush="{StaticResource PhoneForegroundBrush}"
                            Height="80">
                        <TextBlock 
                            Text="{Binding FilePath}" 
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center" 
                            Style="{StaticResource PhoneTextNormalStyle}" />
                    </Border>
                </Grid>
            </DataTemplate>
        </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

上面重要的部分是LongListSelector的ItemsSource、SelectedItem和PlayCommand的绑定(bind)。

我在@Git 上建立了一个小示例项目,希望它能帮助您解决问题https://github.com/mikkoviitala/any-ringtone

它通过 http 获取少量 mp3,将文件保存到 IsoStore,然后在 LongListSelector 中显示项目。点击列表项启动执行 Ringtonetask 的命令。

imgur

关于c# - 音频文件的独立存储不使用单独的点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24367081/

相关文章:

c# - 使用文件中的字体绘制文本不起作用

c# - 你能以编程方式在 C# 中的 ProjectItem 上执行 'Run Custom Tool' 吗?

windows-phone-8 - Windows Phone 公司应用的无配额推送通知

opengl-es - 我可以在 Windows Phone 8 应用程序中使用 OpenGL ES 吗?

.net - .net mcisendstring-使用资源而不是完整路径

html - 使用 Audio API 播放音频流

c# - 运算符 '==' 不能应用于类型 'System.DBNull' 和 'Int' 的操作数

c# - 如何在 C# 中仅向 ref 元素添加命名空间?

c# - 一个 ViewModel 和多个 View

php - 来自PHP服务器的AngularJS流音频