• Go语言,一段奇怪的代码


    一星辰一 2024-04-28 15:47 采纳率: 0%
    浏览 7

    Go语言,一段奇怪的代码

    
    func run() {
        f, _ := os.Open("aa.mp3")
        d, _ := mp3.NewDecoder(f)
        c, _, _ := oto.NewContext(d.SampleRate(), 2, 2)
        p := c.NewPlayer(d)
        p.Play()
        fmt.Println("1")
        time.Sleep(time.Hour)
        fmt.Println("2")
        p.IsPlaying()
        fmt.Println("3")
    }
    

    音乐播放代码片段。有p.IsPlaying()的时候可以正常播放音乐,没有这个东西就播放不了,我不知道为什么,控制台输出也没有差别

    • 写回答
    • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-28 15:47
      关注

      引自免费微信小程序:皆我百晓生

      在分析这段 Go 语言的代码之前,让我们先理解一下它的结构和功能。这段代码的主要目的是打开一个名为 "aa.mp3" 的音频文件,然后使用 mp3 包解码音频,并通过 oto 包创建一个新的音频上下文以及一个播放器实例。之后,它开始播放音乐并打印字符串 "1"。接着,程序会暂停一小时(time.Sleep(time.Hour)),然后打印 "2",紧接着检查播放器是否正在播放音乐(p.IsPlaying())并打印 "3"。

      代码中的关键部分是 p.IsPlaying() 这一行,它用来检查播放器是否还在播放音乐。根据你的描述,如果你去掉这一行,音乐就无法播放。这可能是因为在某些情况下,调用 IsPlaying() 是为了保持与音频系统的连接,确保播放器仍在运行。

      为了确认这一点,我们可以尝试稍微修改代码,使其在播放音乐时定期检查播放状态,而不是只在暂停后检查。这样也许能解决播放问题。下面是修改后的代码:

      package main
      
      import (
      	"fmt"
      	"os"
      	"time"
      
      	"github.com/hajimehoshi/oto"
      	"github.com/mccoyst/mp3"
      )
      
      func main() {
      	run()
      }
      
      func run() {
      	f, err := os.Open("aa.mp3")
      	if err != nil {
      		fmt.Println("Error opening file:", err)
      		return
      	}
      	defer f.Close()
      
      	d, err := mp3.NewDecoder(f)
      	if err != nil {
      		fmt.Println("Error decoding MP3:", err)
      		return
      	}
      
      	c, err := oto.NewContext(d.SampleRate(), 2, 2)
      	if err != nil {
      		fmt.Println("Error creating audio context:", err)
      		return
      	}
      
      	p := c.NewPlayer(d)
      	p.Play()
      
      	fmt.Println("1")
      
      	ticker := time.NewTicker(5 * time.Second) // Check every 5 seconds
      	defer ticker.Stop()
      
      	for range ticker.C {
      		fmt.Println("Checking if playing...")
      		if !p.IsPlaying() {
      			fmt.Println("Restarting playback.")
      			p.Play()
      		}
      	}
      
      	time.Sleep(time.Hour)
      	fmt.Println("2")
      	fmt.Println("3")
      }
      

      在这个版本的代码中,我们添加了一个定时器(ticker)每5秒检查一次播放器的状态。如果发现播放停止,我们就重新启动播放。这样做的目的是确保播放器始终保持活跃状态,即使不直接调用 IsPlaying() 方法,也能保持音乐的连续播放。

      请尝试运行修改后的代码,看看音乐能否持续播放而不会因为移除 IsPlaying() 调用而受到影响。如果还有问题,请告诉我结果。

      展开全部

      评论 编辑记录
    • Kwan的解忧杂货铺 Java领域优质创作者 2024-04-28 15:47
      关注

      下午好🌅🌅🌅
      本答案参考ChatGPT-3.5

      根据提供的代码,可以看出该程序是读取了一首mp3音乐,并使用 oto 库进行播放。但是,如果在播放音乐的过程中,没有调用 p.IsPlaying() 方法,就会出现问题,导致音乐不能正常播放。在控制台输出上,两种情况并没有区别,都输出了 "1",但似乎卡在 time.Sleep(time.Hour) 这里,没有继续往下执行。

      为了解决这个问题,需要做以下几点调整:

      1. time.Sleep(time.Hour) 改为 select{}。让程序阻塞在这里,同时允许其他协程继续执行。
      2. 调用 p.Close() 方法来关闭播放器,让程序安全退出。

      修改后的代码如下:

      func run() {
          f, _ := os.Open("aa.mp3")
          d, _ := mp3.NewDecoder(f)
          c, _, _ := oto.NewContext(d.SampleRate(), 2, 2)
          p := c.NewPlayer(d)
          p.Play()
          fmt.Println("1")
          select{}
          fmt.Println("2")
          p.IsPlaying()
          fmt.Println("3")
          p.Close()
      }
      

      这样就可以正常播放音乐了。同时,程序也可以安全退出了。

      评论
    • 阿里嘎多学长 2024-04-28 15:47
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      问题概括

      这个问题的目的是要解决在Go语言中使用oto库播放MP3文件时,为什么在代码中加入p.IsPlaying()函数调用后,音乐能够正常播放,而去掉这个调用则无法播放。

      问题出现原因

      根据提供的代码片段,问题可能出现的原因可能与程序的执行流程有关。在Go语言中,由于goroutine的调度,如果没有明确的阻塞或等待操作,程序可能会在音乐播放完成之前就退出,导致音乐播放被中断。p.IsPlaying()函数可能隐含了某种形式的阻塞或等待,使得主goroutine在音乐播放完成之前不会退出。

      问题解决方案

      为了确保音乐能够完整播放,可以在代码中添加一个阻塞操作,直到音乐播放完成。这可以通过在p.Play()之后添加一个对p.Wait()的调用来实现,p.Wait()会阻塞直到播放器完成播放。

      提供代码

      package main
      
      import (
      	"fmt"
      	"os"
      	"time"
      
      	"github.com/hajimehoshi/go-mp3"
      	"github.com/hajimehoshi/oto"
      )
      
      func run() {
      	f, _ := os.Open("aa.mp3")
      	defer f.Close() // 确保文件在函数结束时关闭
      
      	d, _ := mp3.NewDecoder(f)
      	c, _, _ := oto.NewContext(d.SampleRate(), 2, 2)
      	p := c.NewPlayer(d)
      
      	p.Play()
      	fmt.Println("1")
      
      	// 等待音乐播放完成
      	p.Wait()
      
      	fmt.Println("2")
      	// p.IsPlaying() 不再需要,因为Wait已经确保了播放完成
      	// fmt.Println("3")
      }
      
      func main() {
      	run()
      }
      

      代码运行方式

      • 确保你的系统中安装了Go语言环境。
      • 将上述代码保存为.go文件,例如main.go
      • 在命令行中运行go run main.go

      代码预期运行结果

      1
      2
      

      音乐文件aa.mp3将被播放,程序将在音乐播放完成后打印出"2"。

      推荐相关链接

      展开全部

      评论 编辑记录
    • GISer Liu 2024-04-28 15:51
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      这段代码中存在一个常见的问题,即在调用p.Play()方法后立即进行了一段time.Sleep()的休眠操作。这样的做法会导致程序在调用p.Play()后立即进入休眠状态,不会等待音乐播放完成就输出"2"和"3",从而使得在没有p.IsPlaying()的情况下看起来似乎音乐没有播放。
      解决这个问题的方法是,可以在播放音乐之后,通过监听音乐播放状态,等待音乐播放完毕再继续执行后续的代码。可以使用p.Play()返回的Play()方法的阻塞版本p.Play(),它会一直阻塞直到音乐播放完成。
      以下是修改后的代码:
      go
      Copy code

      func run() {
      f, _ := os.Open("aa.mp3")
      d, _ := mp3.NewDecoder(f)
      c, _ := oto.NewContext(d.SampleRate(), 2, 2)
      p := c.NewPlayer(d)
      p.Play()
      // 阻塞直到音乐播放完成
      <-p.Play()
      fmt.Println("1")
      time.Sleep(time.Hour)
      fmt.Println("2")
      // 此时可以正常调用 p.IsPlaying() 获取播放状态
      fmt.Println("3")
      }
      

      这样修改后,程序会在音乐播放完成后再输出"2"和"3",并且可以通过p.IsPlaying()方法获取播放状态。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      评论
  • 相关阅读:
    【开题报告】基于微信小程序的时空胶囊系统的设计与实现
    21天学习挑战赛——Python 爬虫入门
    前后端分离不可忽视的陷阱,深入剖析挑战,分享解决方案,助你顺利实施分离开发。
    牛客小白月赛62题解
    什么样的企业最需要MES?
    各类软件docker安装
    uni-app运行到微信开发者工具-没有打印的情况
    【zeno】为zeno增加子模块/新节点的最小化的例子
    C++多线程01
    【笔记】KMeans聚类算法
  • 原文地址:https://ask.csdn.net/questions/8096466